hdu3487Play with Chain(splay)

链接

简单的两种操作,一种删除某段区间,加在第I个点的后面,另一个是翻转区间。都是splay的简单操作。

悲剧一:pushdown时候忘记让lz=0

悲剧二:删除区间,加在某点之后的时候忘记修改其父亲节点。

  1 #include <iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<stdlib.h>
  6 #include<vector>
  7 #include<cmath>
  8 #include<queue>
  9 #include<set>
 10 using namespace std;
 11 #define N 300010
 12 #define LL long long
 13 #define INF 0xfffffff
 14 #define key_value ch[ch[root][1]][0]
 15 const double eps = 1e-8;
 16 const double pi = acos(-1.0);
 17 const double inf = ~0u>>2;
 18 using namespace std;
 19 struct splay_tree
 20 {
 21     int pre[N],size[N];
 22     int ch[N][2];
 23     int root,tot,num,tot1;
 24     int key[N],lz[N];
 25     void dfs(int x)
 26     {
 27         if(x)
 28         {
 29             dfs(ch[x][0]);
 30             printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size=%2d,key=%2d lz = %d\n",
 31                    x,ch[x][0],ch[x][1],pre[x],size[x],key[x],lz[x]);
 32             dfs(ch[x][1]);
 33         }
 34     }
 35     void debug()
 36     {
 37         printf("root:%d\n",root);
 38         dfs(root);
 39     }
 40 //以上用于debug*/
 41     void newnode(int &x,int v,int fa)//新建一结点
 42     {
 43         x = ++tot;
 44         ch[x][0]=ch[x][1] = 0;
 45         pre[x] = fa;
 46         lz[x] = 0;
 47         size[x] = 1;
 48         key[x] = v;
 49     }
 50     void pushdown(int w)
 51     {
 52         if(lz[w])
 53         {
 54             int l = ch[w][0],r = ch[w][1];
 55             swap(ch[w][0],ch[w][1]);
 56
 57             lz[l]^=lz[w];
 58             lz[r]^=lz[w];
 59             lz[w] = 0;
 60         }
 61     }
 62     void pushup(int w)//由儿子更新其父亲
 63     {
 64         size[w] = size[ch[w][0]]+size[ch[w][1]]+1;
 65         //cout<<s[w][0]<<" "<<s[w][1]<<endl;
 66     }
 67     void rotate(int r,int kind)//旋转操作,根据kind进行左旋和右旋
 68     {
 69         int y = pre[r];
 70         pushdown(y);
 71         pushdown(r);
 72         ch[y][!kind] = ch[r][kind];
 73         pre[ch[r][kind]] = y;
 74         if(pre[y])
 75         {
 76             ch[pre[y]][ch[pre[y]][1]==y] = r;
 77         }
 78         pre[r] = pre[y];
 79         ch[r][kind] = y;
 80         pre[y] = r;
 81         pushup(y);
 82         pushup(r);
 83     }
 84     void splay(int r,int goal)//将r结点旋至goal下
 85     {
 86         pushdown(r);
 87         while(pre[r]!=goal)
 88         {
 89             if(pre[pre[r]]==goal)
 90             {
 91                 rotate(r,ch[pre[r]][0]==r);
 92             }
 93             else
 94             {
 95                 int y = pre[r];
 96                 int kind = (ch[pre[y]][0]==y);
 97                 if(ch[y][kind]==r)
 98                 {
 99                     rotate(r,!kind);
100                     rotate(r,kind);
101                 }
102                 else
103                 {
104                     rotate(y,kind);
105                     rotate(r,kind);
106                 }
107             }
108         }
109         pushup(r);
110         if(goal==0) root = r;
111     }
112     int get_k(int k)//得到第k个的结点
113     {
114         int r = root;
115        pushdown(r);
116         while(size[ch[r][0]]+1!=k)
117         {
118             if(size[ch[r][0]]>=k)
119                 r = ch[r][0];
120             else
121             {
122                 k-=(size[ch[r][0]]+1);//根据左右结点的数量来确定第k个节点在哪里
123                 r = ch[r][1];
124             }
125             pushdown(r);
126         }
127         pushup(r);
128         return r;
129     }
130     void cut(int l,int r,int k)
131     {
132         splay(get_k(l),0);
133         splay(get_k(r+2),root);
134         pushdown(ch[root][1]);
135         int nod = key_value;
136         ch[ch[root][1]][0] = 0;
137         pre[nod] = 0;
138         pushup(ch[root][1]);
139         pushup(root);
140         //debug();
141         splay(get_k(k),0);
142         splay(get_k(k+1),root);
143         ch[ch[root][1]][0] = nod;
144         pre[nod] = ch[root][1];
145         pushup(ch[root][1]);
146         pushup(root);
147        // debug();
148     }
149     void filp(int l,int r)
150     {
151         //cout<<get_k(l)<<" "<<get_k(r+2)<<endl;
152         splay(get_k(l),0);
153         splay(get_k(r+2),root); //cout<<","<<endl;debug();
154         lz[key_value]^=1;
155         //swap(ch[key_value][0],ch[key_value][1]);
156         pushup(ch[root][1]);
157         pushup(root);
158     }
159     void work(int n)
160     {
161         int i;
162         for(i = 1 ;i < n ;i++)
163         {
164             printf("%d ",key[get_k(i+1)]);
165         }
166         printf("%d\n",key[get_k(n+1)]);
167         //debug();
168     }
169     void build(int &x,int l,int r,int fa)
170     {
171         int m = (l+r)>>1;
172         if(l>r) return ;
173         newnode(x,m,fa);
174         build(ch[x][0],l,m-1,x);
175         build(ch[x][1],m+1,r,x);
176         pushup(x);
177     }
178     void init(int o)
179     {
180         size[0] = ch[0][0] = ch[0][1] =  key[0] = lz[0] = 0;
181         root = tot = 0;
182         newnode(root,0,0);
183         newnode(ch[root][1],0,root);
184         build(ch[ch[root][1]][0],1,o,ch[root][1]);
185         size[root] = 2;
186         pushup(ch[root][1]);
187         pushup(root);
188     }
189 }SP;
190 int main()
191 {
192     int n,q;
193     while(scanf("%d%d",&n,&q)!=EOF)
194     {
195         if(n==-1&&q==-1) break;
196         SP.init(n);
197         while(q--)
198         {
199             char sq[20];
200             int k,x,y;
201             scanf("%s",sq);
202             if(sq[0]==‘C‘)
203             {
204                 scanf("%d%d%d",&x,&y,&k);
205                 SP.cut(x,y,k+1);
206               // SP.debug();
207 //                SP.work(n);
208             }
209             else
210             {
211                 //SP.debug();
212                 scanf("%d%d",&x,&y);
213                 SP.filp(x,y);
214                 //SP.debug();
215             }
216             //SP.work(n);
217         }
218         SP.work(n);
219     }
220     return 0;
221 }

hdu3487Play with Chain(splay),布布扣,bubuko.com

时间: 2024-10-28 13:42:02

hdu3487Play with Chain(splay)的相关文章

hdu-3487-Play with Chain (Splay tree)

一二三 时间限制:1000 ms  |  内存限制:65535 KB 难度:1 描述     你弟弟刚刚学会写英语的一(one).二(two)和三(three).他在纸上写了好些一二三,可惜有些字母写错了.已知每个单词最多有一个字母写错了(单词长度肯定不会错),你能认出他写的啥吗? 输入 第一行为单词的个数(不超过 10).以下每行为一个单词,单词长度正确,且最多有一个字母写错.所有字母都是小写的. 输出 对于每组测试数据,输出一行,即该单词的阿拉伯数字.输入保证只有一种理解方式. 样例输入 3

Hdu3487-Play with Chain(伸展树分裂合并)

Problem Description YaoYao is fond of playing his chains. He has a chain containing n diamonds on it. Diamonds are numbered from 1 to n. At first, the diamonds on the chain is a sequence: 1, 2, 3, …, n. He will perform two types of operations: CUT a

hdu 3487 Play with Chain(splay区间剪切,翻转)

题目链接:hdu 3487 Play with Chain 题意: cut a b c: 将a到b区间剪切下来,放在第c位置的后面. flip a b: 翻转a到b区间 题解: 第一个操作,选通过旋转,然后使a到b区间变成根的右儿子的左儿子,然后剪掉. 再找到c+1的位置,接上. 第二个操作,区间标记就行. 1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=a;i<=b;++i) 3 using namespace std; 4

HDU3487 Play With Chain [Splay]

题目传送门 题目描述 Problem Description YaoYao is fond of playing his chains. He has a chain containing n diamonds on it. Diamonds are numbered from 1 to n.At first, the diamonds on the chain is a sequence: 1, 2, 3, …, n.He will perform two types of operation

hdu 3487 Play with Chain (Splay)

hdu 3487 Splay树模板题 题意: 一开始给出1 2 3 4 ... n 这样一个序列,对这个序列进行以下两种操作: (1)CUT a b c: 将子串[a,b]切下来,放到剩余串的第c个数之后 . (2) FLIP a b : 将子串[a,b]翻转,如 1 2 3 4 就变成 4 3 2 1 . 总之就是一道Splay树的模板题 ... 1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm&

【HDU 3487】Play with Chain Splay

题意 给定$n$个数序列,每次两个操作,将区间$[L,R]$拼接到去掉区间后的第$c$个数后,或者翻转$[L,R]$ Splay区间操作模板,对于区间提取操作,将$L-1$ Splay到根,再将$R+1$ Splay到根节点的右儿子,那么根节点右儿子的左儿子就对应区间$[L,R]$,对于反转操作,通过懒操作下放 代码 #include <bits/stdc++.h> #define inf 0x7f7f7f7f using namespace std; const int N = 500005

Splay小结

有关论文: 运用伸展树解决数列维护问题 算法合集之<伸展树的基本操作与应用> splay的伸展操作 splay(x,goal)将x节点移到goal节点的下方,通过左旋和右旋基本操作实现,其实现过程在论文中有详细介绍. 对于用splay去维护一个数列,有以下常用操作. 1.splay(x,goal) 将结点k旋转到goal结点的下方 2.getpos(x) 查询第x个节点的在树中的位置. 3.rotateto(x,goal) 将第x个结点旋转到goal结点下方,可以由 rotateto(x,go

【HDU3487】【splay分裂合并】Play with Chain

Problem Description YaoYao is fond of playing his chains. He has a chain containing n diamonds on it. Diamonds are numbered from 1 to n.At first, the diamonds on the chain is a sequence: 1, 2, 3, …, n.He will perform two types of operations:CUT a b c

Splay树——HDU 3487 Play with Chain

对应HDU题目:点击打开链接 Play with Chain Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 4571    Accepted Submission(s): 1859 Problem Description YaoYao is fond of playing his chains. He has a chain cont