码迷,mamicode.com
首页 > 其他好文 > 详细

po3580SuperMemo(splay)

时间:2014-06-20 15:25:14      阅读:214      评论:0      收藏:0      [点我收藏+]

标签:style   class   blog   code   http   tar   

链接

操作不少,不过都是一些基本的操作,增删,旋转,逆转,询问最小。

注意一点:T<0时 让t=0;

旋转的时候,是顺时针旋转,数据范围在int内。

刚开始旋转转错方向了。。

bubuko.com,布布扣
  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 200010
 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 int a[N];
 20 struct splay_tree
 21 {
 22     int pre[N],size[N];
 23     int ch[N][2];
 24     int root,tot;
 25     int lz2[N];
 26     LL s[N],lz1[N],key[N];
 27 //    void dfs(int x)
 28 //    {
 29 //        if(x)
 30 //        {
 31 //            dfs(ch[x][0]);
 32 //            printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size=%2d,key=%2d lz1 = %d lz2 = %d min = %d\n",
 33 //                   x,ch[x][0],ch[x][1],pre[x],size[x],key[x],lz1[x],lz2[x],s[x]);
 34 //            dfs(ch[x][1]);
 35 //        }
 36 //    }
 37 //    void debug()
 38 //    {
 39 //        printf("root:%d\n",root);
 40 //        dfs(root);
 41 //    }
 42 //以上用于debug*/
 43     void newnode(int &x,int v,int fa)//新建一结点
 44     {
 45         x = ++tot;
 46         ch[x][0]=ch[x][1] = 0;
 47         pre[x] = fa;
 48         lz1[x] = lz2[x] = 0;
 49         size[x] = 1;
 50         s[x] = v;
 51         key[x] = v;
 52     }
 53     void pushdown(int w)
 54     {
 55         int l = ch[w][0],r = ch[w][1];
 56         if(lz1[w])
 57         {
 58             lz1[l] += lz1[w];
 59             lz1[r] += lz1[w];
 60             s[l]+=lz1[w];
 61             s[r]+=lz1[w];
 62             key[l]+=lz1[w];
 63             key[r]+=lz1[w];
 64             lz1[w] = 0;
 65         }
 66         if(lz2[w])
 67         {
 68             lz2[l]^=lz2[w];
 69             lz2[r]^=lz2[w];
 70             swap(ch[w][0],ch[w][1]);
 71             lz2[w] = 0;
 72         }
 73     }
 74     void pushup(int w)
 75     {
 76         size[w] = size[ch[w][0]]+size[ch[w][1]]+1;
 77         s[w] = key[w];
 78         if(ch[w][0])
 79             s[w] = min(s[w],s[ch[w][0]]);
 80         if(ch[w][1])
 81             s[w] = min(s[w],s[ch[w][1]]);
 82     }
 83     void rotate(int r,int kind)
 84     {
 85         int y = pre[r];
 86         pushdown(y);
 87         pushdown(r);
 88         ch[y][!kind] = ch[r][kind];
 89         pre[ch[r][kind]] = y;
 90         if(pre[y])
 91         {
 92             ch[pre[y]][ch[pre[y]][1]==y] = r;
 93         }
 94         pre[r] = pre[y];
 95         ch[r][kind] = y;
 96         pre[y] = r;
 97         pushup(y);
 98         pushup(r);
 99     }
100     void splay(int r,int goal)
101     {
102         pushdown(r);
103         while(pre[r]!=goal)
104         {
105             if(pre[pre[r]]==goal)
106             {
107                 rotate(r,ch[pre[r]][0]==r);
108             }
109             else
110             {
111                 int y = pre[r];
112                 int kind = (ch[pre[y]][0]==y);
113                 if(ch[y][kind]==r)
114                 {
115                     rotate(r,!kind);
116                     rotate(r,kind);
117                 }
118                 else
119                 {
120                     rotate(y,kind);
121                     rotate(r,kind);
122                 }
123             }
124         }
125         pushup(r);
126         if(goal==0) root = r;
127     }
128     int get_k(int k)
129     {
130         int r = root;
131         pushdown(r);
132         while(size[ch[r][0]]+1!=k)
133         {
134             if(size[ch[r][0]]>=k)
135                 r = ch[r][0];
136             else
137             {
138                 k-=(size[ch[r][0]]+1);
139                 r = ch[r][1];
140             }
141             pushdown(r);
142         }
143         return r;
144     }
145     void add(int l,int r,int k)
146     {
147         splay(get_k(l),0);
148         splay(get_k(r+2),root);
149         lz1[key_value]+=k;
150         s[key_value]+=k;
151         key[key_value]+=k;
152         pushup(ch[root][1]);
153         pushup(root);
154     }
155     LL query(int l,int r)
156     {
157         splay(get_k(l),0);
158         splay(get_k(r+2),root);
159         return s[key_value];
160     }
161     void reverse(int l,int r)
162     {
163         splay(get_k(l),0);
164         splay(get_k(r+2),root);
165         lz2[key_value]^=1;
166         pushup(ch[root][1]);
167         pushup(root);
168     }
169     void revolve(int l,int r,int k)
170     {
171         splay(get_k(r-k+1),0);
172         splay(get_k(r+2),root);
173         int nod = key_value;
174         key_value = 0;
175         pushup(ch[root][1]);
176         pushup(root);
177 
178         splay(get_k(l),0);
179         splay(get_k(l+1),root);
180         key_value = nod;
181         pre[nod] = ch[root][1];
182         pushup(ch[root][1]);
183         pushup(root);
184     }
185     void insert(int k,int p)
186     {
187         splay(get_k(k),0);
188         splay(get_k(k+1),root);
189         newnode(key_value,p,ch[root][1]);
190         pushup(ch[root][1]);
191         pushup(root);
192     }
193     void updelete(int k)
194     {
195         splay(get_k(k),0);
196         splay(get_k(k+2),root);
197         key_value = 0;
198         pushup(ch[root][1]);
199         pushup(root);
200     }
201     void build(int &x,int l,int r,int fa)
202     {
203         int m = (l+r)>>1;
204         if(l>r) return ;
205         newnode(x,a[m],fa);
206         build(ch[x][0],l,m-1,x);
207         build(ch[x][1],m+1,r,x);
208         pushup(x);
209     }
210     void init(int o)
211     {
212         int i;
213         for(i = 1; i <= o ; i++)
214             scanf("%d",&a[i]);
215         size[0] = ch[0][0] = ch[0][1] =  key[0] = lz1[0] = lz2[0] = s[0] = 0;
216         root = tot = 0;
217         newnode(root,0,0);
218         newnode(ch[root][1],0,root);
219         build(ch[ch[root][1]][0],1,o,ch[root][1]);
220         size[root] = 2;
221         pushup(ch[root][1]);
222         pushup(root);
223     }
224 //    void work()
225 //    {
226 //        for(int i =  1; i <= size[root] ;i++)
227 //        cout<<key[get_k(i)]<<" ";
228 //        puts("");
229 //    }
230 } SP;
231 int main()
232 {
233     int n,q,k,x,y;
234     char sq[10];
235     while(scanf("%d",&n)!=EOF)
236     {
237         SP.init(n);
238         scanf("%d",&q);
239         while(q--)
240         {
241             scanf("%s",sq);
242             if(sq[0]==A)
243             {
244                 scanf("%d%d%d",&x,&y,&k);
245                 SP.add(x,y,k);
246             }
247             else if(strcmp(sq,"REVERSE")==0)
248             {
249                 scanf("%d%d",&x,&y);
250                 SP.reverse(x,y);
251             }
252             else if(strcmp(sq,"REVOLVE")==0)
253             {
254                 scanf("%d%d%d",&x,&y,&k);
255                 if(k<=0) continue;
256                 k = k%(y-x+1);
257                 SP.revolve(x,y,k);
258             }
259             else if(sq[0]==I)
260             {
261                 scanf("%d%d",&k,&x);
262                 SP.insert(k+1,x);
263             }
264             else if(sq[0]==D)
265             {
266                 scanf("%d",&k);
267                 SP.updelete(k);
268             }
269             else if(sq[0]==M)
270             {
271                 scanf("%d%d",&x,&y);
272                 printf("%d\n",SP.query(x,y));
273             }
274             //SP.work();
275         }
276     }
277     return 0;
278 }
View Code

 

po3580SuperMemo(splay),布布扣,bubuko.com

po3580SuperMemo(splay)

标签:style   class   blog   code   http   tar   

原文地址:http://www.cnblogs.com/shangyu/p/3796675.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!