【hdu3487】【splay】Play with Chain
2013-03-04 21:53
453 查看
题目大意是一串链子,要求支持两项操作:
1、从链子中切下a-b区间,然后整体插入到位置k的数的后面(注意这里的k是对于切下之后的位置k)。
2、翻转a-b这个区间的数
这道题是典型的splay题目。
具体操作就是:先提取出a-b这一段区间,然后记录一下区间位置,并且清除,然后再提取出第k个数,插入即可。
第二个操作则是使用lazy标记,不断交换左右子树,实现翻转。
代码:
1、从链子中切下a-b区间,然后整体插入到位置k的数的后面(注意这里的k是对于切下之后的位置k)。
2、翻转a-b这个区间的数
这道题是典型的splay题目。
具体操作就是:先提取出a-b这一段区间,然后记录一下区间位置,并且清除,然后再提取出第k个数,插入即可。
第二个操作则是使用lazy标记,不断交换左右子树,实现翻转。
代码:
#include<cstdio> #include<cstring> #define keyTree ch[ ch[root][1] ][0] using namespace std; const int maxn = 300000 + 10; int n,m; int num; int root,top; struct SplayTree { int ch[maxn][2],pre[maxn]; int val[maxn],sz[maxn]; bool reserve[maxn]; void push_up(int x) { sz[x] = sz[ ch[x][0] ] + sz[ ch[x][1] ] + 1; } void swap(int &a,int &b) { int t = a;a = b;b = t; } void push_down(int x) { if(reserve[x]) { if(ch[x][0])reserve[ ch[x][0] ] = !reserve[ ch[x][0] ]; if(ch[x][1])reserve[ ch[x][1] ] = !reserve[ ch[x][1] ]; swap(ch[x][0],ch[x][1]); reserve[x] = false; } } void Rotate(int x,int f) { int y = pre[x]; push_down(y); push_down(x); ch[y][!f] = ch[x][f]; pre[ ch[x][f] ] = y; pre[x] = pre[y]; if(pre[x])ch[ pre[x] ][ ch[pre[x]][1] == y ] = x; ch[x][f] = y; pre[y] = x; push_up(y); } void Splay(int x,int goal) { push_down(x); while(pre[x] != goal) { if(pre[pre[x]] == goal)Rotate(x,ch[pre[x]][0] == x); else { int y = pre[x],z = pre[y]; int f = (ch[z][0] == y); if(ch[y][f] == x)Rotate(x, !f),Rotate(x ,f); else Rotate(y,f),Rotate(x,f); } } push_up(x); if(goal == 0)root = x; } void RotateTo(int k,int goal) { int x = root; push_down(x); while(sz[ ch[x][0] ] != k) { if(k < sz[ ch[x][0] ])x = ch[x][0]; else { k -= (sz[ ch[x][0] ] + 1); x = ch[x][1]; } push_down(x); } Splay(x,goal); } void work(int l,int r,int k) { RotateTo(l - 1,0); RotateTo(r + 1,root); int tmp = keyTree; keyTree = 0; push_up(ch[root][1]); push_up(root); RotateTo(k,0); RotateTo(k + 1,root); keyTree = tmp; pre[tmp] = ch[root][1]; push_up(keyTree); push_up(root); } void res(int l,int r) { RotateTo(l - 1,0); RotateTo(r + 1,root); reserve[ keyTree ] = !reserve[ keyTree ]; } void output(int x,int n) { push_down(x); if(ch[x][0])output(ch[x][0],n); if(val[x] >= 1 && val[x] <= n) { num++; if(num == 1)printf("%d",val[x]); else printf(" %d",val[x]); } if(ch[x][1])output(ch[x][1],n); } void Newnode(int &x,int c) { x = ++top; ch[x][0] = ch[x][1] = pre[x] = 0; reserve[x] = false; val[x] = c; sz[x] = 1; } void makeTree(int &x,int l,int r,int f) { if(l > r)return; int m = (l + r) >> 1; Newnode(x,m); makeTree(ch[x][0],l,m - 1,x); makeTree(ch[x][1],m + 1,r,x); pre[x] = f; push_up(x); } void init() { memset(ch,0,sizeof(ch)); memset(pre,0,sizeof(pre)); memset(val,0,sizeof(val)); ch[0][0] = ch[0][1] = pre[0] = sz[0] = 0; root = top = 0; Newnode(root,-1); Newnode(ch[root][1],-1); pre[ch[root][1]] = root; makeTree(keyTree,1,n,ch[root][1]); push_up(ch[root][1]); push_up(root); } }Spt; void init() { freopen("hdu3487.in","r",stdin); freopen("hdu3487.out","w",stdout); } void readdata() { while(scanf("%d%d",&n,&m) != EOF) { if(n == -1 && m == -1)continue; Spt.init(); for(int i = 1;i <= m;i++) { char op[2]; int l,r; scanf("%s",op); if(op[0] == 'C') { int k; scanf("%d%d%d",&l,&r,&k); Spt.work(l,r,k); } else { scanf("%d%d",&l,&r); Spt.res(l,r); } } num = 0; Spt.output(root,n); printf("\n"); } } int main() { init(); readdata(); return 0; }
相关文章推荐
- HDU3487 Play with Chain (Splay)
- 【HDU3487】【splay分裂合并】Play with Chain
- HDU3487 Play with Chain(Splay)
- hdu3487 Play with Chain(Splay)
- hdu3487 Play with Chain splay
- hdu3487 Play with Chain 伸展树splay
- hdu3487 Play with Chain(splay)
- hdu3487 Play with Chain (Splay)
- hdu 3487 Play with Chain splay
- hdu3487 Play with Chain
- hdu 3487 Play with Chain splay tree
- HDU 3487 Play with Chain [splay]
- hdu 3487 Play with Chain(splay)
- hdu 3487 Play with Chain (Splay树) 区间切割 插入 翻转
- Hdu3487-Play with Chain(伸展树分裂合并)
- HDU - 3487 Play with Chain __ Splay
- HDU 3487 Play with Chain 伸展树splay
- HDU 3478 Play with Chain (Splay树)
- HDU 3487 Play with Chain(Splay 经典操作)
- HDU 3487 Play with Chain | Splay