Shuffle Cards(牛客第三场+splay)
题目:


题意:将1~n的数进行m次操作,每次操作将第pi位到pi+si-1位的数字移到第一位,求最后的排列。
思路:现在还没不会写splay,在知道这是splay模板题后找了一波别人的模板,虽然过了,但是感觉自己没学到什么,过几天去学一波splay,再回来把这题重写一次~
代码实现如下:
#include <map>
#include <set>
#include <cmath>
#include <ctime>
#include <stack>
#include <queue>
#include <cstdio>
#include <cctype>
#include <bitset>
#include <string>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <functional>
#include <bits/stdc++.h>
#define debug(x) cout<<"["<<x<<"]";
#define FIN freopen("input.txt","r",stdin);
#define FOUT freopen("output.txt","w+",stdout); inline int read() {//读入挂
int ret = , c, f = ;
for(c = getchar(); !(isdigit(c) || c == '-'); c = getchar());
if(c == '-')
f = -, c = getchar();
for(; isdigit(c); c = getchar())
ret = ret * + c - '';
if(f < )
ret = -ret;
return ret;
} const int MX = 1e5 + ;
const int INF = 0x3f3f3f3f; int size[MX];
int num[MX], col[MX], n, m;
int son[MX][], fa[MX], root, sz;
void Link(int x, int y, int c) {
fa[x] = y;
son[y][c] = x;
}
void push_up(int rt) {
size[rt] = size[son[rt][]] + size[son[rt][]] + ;
}
void push_down(int rt) {
if(col[rt]) {
col[son[rt][]] ^= ;
col[son[rt][]] ^= ;
int x = son[rt][];
son[rt][] = son[rt][];
son[rt][] = x;
col[rt] = ;
}
}
void Rotate(int x, int c) {
int y = fa[x];
push_down(y);
push_down(x);
Link(x, fa[y], son[fa[y]][] == y);
Link(son[x][!c], y, c);
Link(y, x, !c);
push_up(y);
} /*把节点x旋转到g的下面*/ void Splay(int x, int g) {
push_down(x); /*剪断[a,b]放到c后面*/
while(fa[x] != g) {
int y = fa[x], cx = son[y][] == x, cy = son[fa[y]][] == y;
if(fa[y] == g)
Rotate(x, cx);
else {
if(cx == cy)
Rotate(y, cy);
else
Rotate(x, cx);
Rotate(x, cy);
}
}
push_up(x);
if(!g)
root = x;
}
void NewNode(int f, int &rt) {
rt = ++sz;
fa[rt] = f, size[rt] = ;
son[rt][] = son[rt][] = col[rt] = ;
} /*把第k个找出来,放到g的下面*/ int Select(int k, int g) {
int rt = root;
while(size[son[rt][]] != k) {
if(size[son[rt][]] > k)
rt = son[rt][];
else
k -= size[son[rt][]] + , rt = son[rt][];
push_down(rt);
}
Splay(rt, g);
return rt;
}
void Build(int l, int r, int &rt, int f) {
if(l > r)
return;
int m = (l + r) >> , t;
NewNode(f, rt);
num[rt] = m;
Build(l, m - , son[rt][], rt);
Build(m + , r, son[rt][], rt);
push_up(rt);
}
void Prepare(int n) {
sz = ;
NewNode(, root);
num[] = ;
NewNode(root, son[root][]);
num[] = ;
Build(, n, son[][], );
Splay(, );
}
void Print(int rt, int &DFN) {
if(!rt)
return;
push_down(rt);
Print(son[rt][], DFN);
if(num[rt])
printf("%d%c", num[rt], ++DFN == n ? '\n' : ' ');
Print(son[rt][], DFN);
}
void Flip(int l, int r) {
Select(l - , );
Select(r + , root);
col[son[son[root][]][]] ^= ;
} void Cut(int a, int b, int c) {
Select(a - , ); /*平衡树操作*/
Select(b + , root);
int w = son[son[root][]][];
son[son[root][]][] = ;
Splay(son[root][], );
Select(c, );
Select(c + , root);
son[son[root][]][] = w;
Splay(son[root][], );
}
void NewNode(int f, int x, int &rt) {
rt = ++sz;
fa[rt] = f, size[rt] = ;
son[rt][] = son[rt][] = ;
num[rt] = x;
}
int Kth(int k) {
int rt = root;
while(size[son[rt][]] != k) {
if(size[son[rt][]] > k)
rt = son[rt][];
else
k -= size[son[rt][]] + , rt = son[rt][];
}
Splay(rt, );
return num[rt];
}
void Insert(int x) {
int rt = root;
while(true) {
int nxt = x > num[rt];
if(!son[rt][nxt]) {
NewNode(rt, x, son[rt][nxt]);
Splay(sz, );
return;
}
rt = son[rt][nxt];
}
} int main() {
while(~scanf("%d%d", &n, &m)) {
Prepare(n);
int x, y;
for(int i = ; i < m; i++) {
scanf("%d%d", &x, &y);
Cut(x, x + y - , );
}
int DFN = ;
Print(root, DFN);
}
return ;
}
Shuffle Cards(牛客第三场+splay)的更多相关文章
- 牛客第三场多校 E Sort String
链接:https://www.nowcoder.com/acm/contest/141/E来源:牛客网 Eddy likes to play with string which is a sequen ...
- 牛客第三场多校 H Diff-prime Pairs
链接:https://www.nowcoder.com/acm/contest/141/H来源:牛客网 Eddy has solved lots of problem involving calcul ...
- uestc summer training #9 牛客第三场 BFS计数
G.coloring tree BFS计数 题目:给你n(<=5000)个节点的一颗树 你有K(<=5000)种颜色 你可以给每一个节点染一种颜色 总共有Kn种染色方法 在一种染色方法中 ...
- PACM Team(牛客第三场多校赛+dp+卡内存+打印路径)
题目链接(貌似未报名的不能进去):https://www.nowcoder.com/acm/contest/141/A 题目: 题意:背包题意,并打印路径. 思路:正常背包思路,不过五维的dp很容易爆 ...
- 牛客第三场 J LRU management
起初看到这道题的时候,草草就放过去了,开了另一道题,结果开题不顺利,总是感觉差一点就可以做出来,以至于一直到最后都没能看这道题qaq 题意:类似于操作系统上讲的LRU算法,有两个操作,0操作代表访问其 ...
- 最长相同01数的子串(map搞搞)--牛客第三场 -- Crazy Binary String
题意: 如题. 或者用我的数组分治也可以,就是有点愚蠢. //#include <bits/stdc++.h> #include <map> #include <iost ...
- 平面割线平分点(构造)--牛客第三场-- Magic Line
题意: 给你n个点的坐标,让你给出两个点,这两个点的连线可以平分这些点. 思路: 先按y的大小排序,在按x的小排序,再搞一下就行了.如下图: #include <bits/stdc++.h> ...
- 牛客第五场多校 J plan 思维
链接:https://www.nowcoder.com/acm/contest/143/J来源:牛客网 There are n students going to travel. And hotel ...
- 牛客第五场 G max 思维
链接:https://www.nowcoder.com/acm/contest/143/G来源:牛客网 Give two positive integer c, n. You need to find ...
随机推荐
- iOS开发开辟线程总结--NSThread
1.简介: 1.1 iOS有三种多线程编程的技术,分别是: 1..NSThread 2.Cocoa NSOperation (iOS多线程编程之NSOperation和NSOperationQueue ...
- TCP系列05—连接管理—4、TCP连接的ISN、连接建立超时及TCP的长短连接
一.TCP连接的ISN 之前我们说过初始建立TCP连接的时候的系列号(ISN)是随机选择的,那么这个系列号为什么不采用一个固定的值呢?主要有两方面的原因 防止同一个连接的不同实例(di ...
- 《学习OpenCV》课后习题解答5
题目:(P104) 为一个图像创建多个图像头.读取一个大小至少为100*100的图像.另创建两个图像头并设置它们的origion,depth,nChannels和widthStep属性同之前读取的图像 ...
- Error:Unable to tunnel through proxy. Proxy returns "HTTP/1.1 400 Bad Request"
(1) 网上下载了一个android应用:死活用不了,查了以下,原来是android studio版本不对,于是把android studio的版本从2.2 升级到3.0,后来发现没法升级,只能下载, ...
- [剑指Offer] 54.字符流中的第一个不重复的字符
题目描述 请实现一个函数用来找出字符流中第一个只出现一次的字符.例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g".当从该字符流中读出 ...
- 调用init方法 两种方式 一个是浏览器方法 一个是 xml中手工配置(load-on-startup)
调用init方法 两种方式 一个是浏览器方法 一个是 xml中手工配置(load-on-startup)
- Andorid API Package ---> android
包名: android Added in API level 1 URL:http:// ...
- Spring-Boot基于配置按条件装Bean
背景 同一个接口有多种实现,项目启动时按某种规则来选择性的启用其中一种实现,再具体一点,比如Controller初始化的时候,根据配置文件的指定的实现类前缀,来记载具体Service,不同Servic ...
- 浅谈Hibernate框架(一)——.hbm.xml中的配置
Hibernate一枚“全自动”的ORM框架: 用IDE工具集成Hibernate会自动生成: 以.hbm.xml为后缀结尾的配置文件+ POJO类 + Dao类 主键查询: Session.load ...
- [CQOI2017]小Q的表格——反演好题
zhoutb2333的题解 难得一见的新颖反演题. 一眼看可能不是反演题. 修改影响别的,很恶心. 所以考虑化简f的联系式,发现和gcd有关 于是考虑用gcd来表示所有的gcd(a,b)=g的所有f( ...