POJ3468/splay树/成段更新

板子题,正在努力看懂板子。。

http://blog.csdn.net/acm_cxlove/article/details/7815019

http://www.cnblogs.com/kuangbin/archive/2013/04/21/3034081.html

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 
  5 #define keyTree (ch[ ch[root][1] ][0])
  6 #define LL long long
  7 
  8 using namespace std;
  9 
 10 const int maxn = 222222;
 11 
 12 struct SpalyTree{
 13     int sz[maxn];
 14     int ch[maxn][2];
 15     int pre[maxn];
 16     int root,top1,top2;
 17     int ss[maxn], que[maxn];
 18 
 19     void Rotate(int x,int f)
 20     {
 21         int y = pre[x];
 22         push_down(y);
 23         push_down(x);
 24         ch[y][!f] = ch[x][f];
 25         pre[ ch[x][f]] = y;
 26         pre[x] = pre[y];
 27         if(pre[x]) ch[pre[y] ][ch[pre[y]][1]==y ] = x;
 28         ch[x][f] = y;
 29         pre[y] = x;
 30         push_up(y);
 31     }
 32     void Splay(int x,int goal)
 33     {
 34         push_down(x);
 35         while(pre[x] != goal)
 36         {
 37             if(pre[pre[x] ] == goal)
 38             {
 39                 Rotate(x,ch[pre[x] ][0] == x);
 40             }
 41             else
 42             {
 43                 int y = pre[x],z = pre[y];
 44                 int f = (ch[z][0] == y);
 45                 if(ch[y][f] == x)
 46                 {
 47                     Rotate(x,!f),Rotate(x,f);
 48                 }
 49                 else
 50                 {
 51                     Rotate(y,f),Rotate(x,f);
 52                 }
 53             }
 54         }
 55         push_up(x);
 56         if(goal == 0) root = x;
 57     }
 58     void RotateTo(int k,int goal)
 59     {
 60         int x = root;
 61         push_down(x);
 62         while(sz[ ch[x][0] ] != k)
 63         {
 64             if(k < sz[ ch[x][0] ])
 65             {
 66                 x = ch[x][0];
 67             }
 68             else
 69             {
 70                 k -= (sz[ch[x][0] ] + 1);
 71                 x = ch[x][1];
 72             }
 73             push_down(x);
 74         }
 75         Splay(x,goal);
 76     }
 77     void erase(int x)
 78     {
 79         int father = pre[x];
 80         int head = 0,tail = 0;
 81         for(que[tail++] = x;head < tail;head++)
 82         {
 83             ss[top2++] = que[head];
 84             if(ch[que[head] ][0]) que[tail++] = ch[que[head] ][0];
 85             if(ch[que[head] ][1]) que[tail++] = ch[que[head] ][1];
 86         }
 87         ch[father ][ch[father][1]==x ] = 0;
 88         push_up(father);
 89     }
 90     void debug(){printf("%d\n",root);Treaval(root);}
 91     void Treaval(int x)
 92     {
 93         if(x)
 94         {
 95             Treaval(ch[x][0]);
 96             printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size = %2d ,val = %2d\n",x,ch[x][0],ch[x][1],pre[x],sz[x],val[x]);
 97             Treaval(ch[x][1]);
 98         }
 99     }
100     void NewNode(int &x,int c)
101     {
102         if(top2) x = ss[--top2];
103         else x = ++top1;
104         ch[x][0] = ch[x][1] = pre[x] = 0;
105         sz[x] = 1;
106 
107         val[x] = sum[x] = c;
108         add[x] = 0;
109     }
110     void push_down(int x)
111     {
112         if(add[x])
113         {
114             val[x] += add[x];
115             add[ch[x][0] ] += add[x];
116             add[ch[x][1] ] += add[x];
117             sum[ch[x][0] ] += (LL)sz[ch[x][0] ]*add[x];
118             sum[ch[x][1] ] += (LL)sz[ch[x][1] ]*add[x];
119             add[x] = 0;
120         }
121     }
122     void push_up(int x)
123     {
124         sz[x] = 1+sz[ch[x][0] ] + sz[ch[x][1] ];
125         sum[x] = add[x] + val[x] + sum[ch[x][0] ] + sum[ch[x][1] ];
126     }
127     void makeTree(int &x,int l,int r,int f)
128     {
129         if(l > r) return ;
130         int m = (l+r)>>1;
131         NewNode(x,num[m]);
132         makeTree(ch[x][0],l,m-1,x);
133         makeTree(ch[x][1],m+1,r,x);
134         pre[x] = f;
135         push_up(x);
136     }
137     void init(int n)
138     {
139         ch[0][0] = ch[0][1] = pre[0] = sz[0] = 0;
140         add[0] = sum[0] = 0;
141 
142         root = top1 = 0;
143         NewNode(root, -1);
144         NewNode(ch[root][1],-1);
145         pre[top1] = root;
146         sz[root] = 2;
147 
148         for(int i=0;i<n;i++)
149             scanf("%d",&num[i]);
150         makeTree(keyTree,0,n-1,ch[root][1]);
151         push_up(ch[root][1]);
152         push_up(root);
153     }
154     void update()
155     {
156         int l,r,c;
157         scanf("%d%d%d",&l,&r,&c);
158         RotateTo(l-1,0);
159         RotateTo(r+1,root);
160         add[keyTree] += c;
161         sum[keyTree] += (LL)c*sz[keyTree];
162     }
163     void query()
164     {
165         int l,r;
166         scanf("%d%d",&l,&r);
167         RotateTo(l-1,0);
168         RotateTo(r+1,root);
169         printf("%lld\n",sum[keyTree]);
170     }
171 
172     int num[maxn];
173     int val[maxn];
174     int add[maxn];
175     LL  sum[maxn];
176 }spt;
177 
178 int n,m;
179 
180 int main()
181 {
182     while(~scanf("%d%d",&n,&m))
183     {
184         spt.init(n);
185         char op[2];
186         for(int i=0;i<m;i++)
187         {
188             scanf("%s",op);
189             if(op[0] == 'Q')
190             {
191                 spt.query();
192             }
193             else
194                 spt.update();
195         }
196     }
197 }

 

posted @ 2016-05-14 17:54  Helica  阅读(208)  评论(0编辑  收藏  举报