王学长的AAA树

让我们响应王学长的号召勇敢的分开写splay和lct吧!

分开写大法好!!!!!!!!!!!杜教的ch[4]弱爆了!!!!

  1 #include <stdio.h>
  2 #include <algorithm>
  3 char ch;
  4 inline void read(int &x)
  5 {
  6     x=0;ch=getchar();
  7     while(ch<=32) ch=getchar();
  8     while(ch>32) x=x*10+ch-48,ch=getchar();
  9 };
 10 
 11 inline void G(int x){while(x--) getchar();}
 12 
 13 #define MAXN 50005
 14 #define MAXM 250005
 15 
 16 int n,q;
 17 
 18 struct Info{
 19     int mi,size;
 20     long long sum;
 21 };
 22 
 23 const int NULL_TAG=0;
 24 const Info NULL_INFO=(Info){2147483647,0,0};
 25 
 26 inline Info operator + (const Info &a,const Info &b)
 27 {
 28     return (Info){std::min(a.mi,b.mi),a.size+b.size,a.sum+b.sum};
 29 };
 30 
 31 inline Info operator * (const Info &a,const int &b)
 32 {
 33     return a.size ? (Info){a.mi+b,a.size,a.sum+1LL*a.size*b}: a;
 34 };
 35 
 36 struct TopTree{
 37     
 38     struct splay_node{
 39         splay_node *ch[2],*fa;
 40         Info x,sum;
 41         int tag,tag_sum;
 42         
 43         inline void add_tag(int t)
 44         {
 45             tag=tag+t;tag_sum=tag_sum+t;
 46             x=x*t;sum=sum*t;
 47         };
 48         
 49         inline void down()
 50         {
 51             if(ch[0]) ch[0]->add_tag(tag);
 52             if(ch[1]) ch[1]->add_tag(tag);
 53             tag=NULL_TAG;
 54         };
 55         
 56         inline void update()
 57         {
 58             sum=x;
 59             if(ch[0]) sum=sum+ch[0]->sum;
 60             if(ch[1]) sum=sum+ch[1]->sum;
 61         };
 62         
 63     };
 64     
 65     splay_node _nodes[MAXN];
 66     
 67     inline int get_parent(splay_node *x,splay_node *&fa)
 68     {
 69         return (fa=x->fa) ? fa->ch[1]==x : -1;
 70     };
 71     
 72     inline void rotate(splay_node *x)
 73     {
 74         int t1,t2;
 75         splay_node *fa,*gfa;
 76         t1=get_parent(x,fa);
 77         t2=get_parent(fa,gfa);
 78         if((fa->ch[t1]=x->ch[t1^1])) fa->ch[t1]->fa=fa;
 79         fa->fa=x;x->fa=gfa;x->ch[t1^1]=fa;
 80         if(t2!=-1) gfa->ch[t2]=x;
 81         fa->update();
 82     };
 83     
 84     inline void pushdown(splay_node *x)
 85     {
 86         static splay_node *stack[MAXN];
 87         int cnt=0;
 88         while(x) stack[cnt++]=x,x=x->fa;
 89         while(cnt--) stack[cnt]-> down();
 90     };
 91     
 92     inline splay_node * splay(splay_node *x)
 93     {
 94         pushdown(x);
 95         while(1){
 96             int t1,t2;
 97             splay_node *fa,*gfa;
 98             t1=get_parent(x,fa);
 99             if(t1==-1) break;
100             t2=get_parent(fa,gfa);
101             if(t2==-1){
102                 rotate(x);break;
103             }else if(t1==t2){
104                 rotate(fa);rotate(x);
105             }else{
106                 rotate(x);rotate(x);
107             };
108         };
109         x->update();
110         return x;
111     };
112     
113     inline splay_node * join(splay_node *L,splay_node *R)
114     {
115         if(!L) return R;
116         if(!R) return L;
117         while(L->ch[1]) L-> down(),L=L->ch[1];
118         splay(L)->ch[1]=R;
119         R->fa=L;
120         L->update();
121         return L;
122     };
123     
124     static splay_node *root[MAXN];
125     
126     struct lct_node{
127         lct_node *ch[2],*fa,*first,*last;
128         bool rev;
129         
130         Info x,sum,tree,all;
131         int chain_tag,tree_tag;
132         
133         inline void add_rev_tag()
134         {
135             std::swap(ch[0],ch[1]);
136             std::swap(first,last);
137             rev^=1;
138         };
139         
140         inline void add_chain_tag(int t)
141         {
142             x=x*t;sum=sum*t;
143             chain_tag=chain_tag+t;
144             all=sum+tree;
145         };
146         
147         inline void add_tree_tag(int t);
148         
149         inline void down()
150         {
151             if(rev){
152                 if(ch[0]) ch[0]->add_rev_tag();
153                 if(ch[1]) ch[1]->add_rev_tag();
154                 rev=0;
155             };
156             if(ch[0]) ch[0]->add_chain_tag(chain_tag),ch[0]->add_tree_tag(tree_tag);
157             if(ch[1]) ch[1]->add_chain_tag(chain_tag),ch[1]->add_tree_tag(tree_tag);
158             chain_tag=tree_tag=NULL_TAG;
159         };
160         
161         inline void update();
162     };
163     
164     static lct_node lct[MAXN];
165     
166     inline int get_parent(lct_node *x,lct_node *&fa)
167     {
168         return (fa=x->fa) ? fa->ch[0]==x?0:fa->ch[1]==x?1:-1 : -1;
169     };
170     
171     inline void rotate(lct_node *x)
172     {
173         int t1,t2;
174         lct_node *fa,*gfa;
175         t1=get_parent(x,fa);
176         t2=get_parent(fa,gfa);
177         if((fa->ch[t1]=x->ch[t1^1])) fa->ch[t1]->fa=fa;
178         fa->fa=x;x->fa=gfa;x->ch[t1^1]=fa;
179         if(t2!=-1) gfa->ch[t2]=x;
180         fa->update();
181     };
182     
183     inline void pushdown(lct_node *x)
184     {
185         static lct_node *stack[MAXN];
186         int cnt=0;
187         while(1){
188             stack[cnt++]=x;
189             lct_node *fa=x->fa;
190             if(!fa || (fa->ch[0]!=x && fa->ch[1]!=x)) break;
191             x=fa;
192         };
193         while(cnt--) stack[cnt]-> down();
194     };
195     
196     inline lct_node * splay(lct_node *x)
197     {
198         pushdown(x);
199         while(1){
200             int t1,t2;
201             lct_node *fa,*gfa;
202             t1=get_parent(x,fa);
203             if(t1==-1) break;
204             t2=get_parent(fa,gfa);
205             if(t2==-1){
206                 rotate(x);break;
207             }else if(t1==t2){
208                 rotate(fa);rotate(x);
209             }else{
210                 rotate(x);rotate(x);
211             };
212         };
213         x->update();
214         return x;
215     };
216     
217     inline lct_node * access(lct_node *x);
218     inline void setroot(int x);
219     inline void modifychain(int x,int y,int t);
220     inline void modifysubtree(int x,int y,int t);
221     inline Info query_chain(int x,int y);
222     inline Info query_subtree(int x,int y);
223     inline void link(int x,int y);
224     inline void cut(int x,int y);
225     inline void init(int *a);
226     
227 }_toptree;
228 
229 TopTree::lct_node TopTree::lct[MAXN];
230 TopTree::splay_node *TopTree::root[MAXN];
231 
232 inline void TopTree::lct_node::add_tree_tag(int t)
233 {
234     tree=tree*t;
235     tree_tag=tree_tag+t;
236     all=sum+tree;
237     int id=this-TopTree::lct;
238     if(root[id]){
239         root[id]->add_tag(t);
240     };
241 };
242 
243 inline void TopTree::lct_node::update()
244 {
245     sum=x;tree=NULL_INFO;
246     int id=this-TopTree::lct;
247     if(root[id]){
248         tree=tree+root[id]->sum;
249     };
250     if(ch[0]) sum=sum+ch[0]->sum,tree=tree+ch[0]->tree;
251     if(ch[1]) sum=sum+ch[1]->sum,tree=tree+ch[1]->tree;
252     all=sum+tree;
253     first=ch[0]?ch[0]->first:this;
254     last=ch[1]?ch[1]->last:this;
255 };
256 
257 inline TopTree::lct_node * TopTree::access(TopTree::lct_node *x)
258 {
259     TopTree::lct_node *ret=NULL;
260     while(x){
261         splay(x);
262         int X=x-TopTree::lct;
263         if(x->ch[1]){
264             int id=x->ch[1]->first-TopTree::lct;
265             splay_node *p=_nodes+id;
266             p->ch[0]=root[X];
267             if(root[X]) root[X]->fa=p;
268             p->ch[1]=NULL;
269             p->fa=NULL;
270             p->x=x->ch[1]->all;
271             p->tag=p->tag_sum=NULL_TAG;
272             p->update();
273             root[X]=p;
274             x->ch[1]=NULL;
275         };
276         if(ret){
277             int id=ret->first-TopTree::lct;
278             splay_node *p=_nodes+id;
279             splay(p);
280             if(p->ch[0]) p->ch[0]->fa=NULL;
281             if(p->ch[1]) p->ch[1]->fa=NULL;
282             root[X]=join(p->ch[0],p->ch[1]);
283             ret->add_chain_tag(p->tag_sum),ret->add_tree_tag(p->tag_sum);
284             x->ch[1]=ret;
285         };
286         x->update();
287         ret=x;x=x->fa;
288     };
289     return ret;
290 };
291 
292 inline void TopTree::setroot(int x)
293 {
294     access(TopTree::lct+x)->add_rev_tag();
295 };
296 
297 inline void TopTree::modifychain(int x,int y,int t)
298 {
299     setroot(x);
300     access(TopTree::lct+y)->add_chain_tag(t);
301 };
302 
303 inline void TopTree::modifysubtree(int x,int y,int t)
304 {
305     setroot(x);
306     access(TopTree::lct+y),splay(TopTree::lct+y);
307     TopTree::lct[y].x=TopTree::lct[y].x*t;
308     if(root[y]) root[y]->add_tag(t);
309     TopTree::lct[y].update();
310 };
311 
312 inline Info TopTree::query_chain(int x,int y)
313 {
314     setroot(x);
315     return access(TopTree::lct+y)->sum;
316 };
317 
318 inline Info TopTree::query_subtree(int x,int y)
319 {
320     setroot(x);
321     access(TopTree::lct+y),splay(TopTree::lct+y);
322     return root[y] ? TopTree::lct[y].x+root[y]->sum : TopTree::lct[y].x;
323 };
324 
325 inline void TopTree::link(int x,int y)
326 {
327     setroot(x);
328     splay(TopTree::lct+x)->fa=TopTree::lct+y;
329     access(TopTree::lct+y);
330     splay(TopTree::lct+y)->ch[1]=TopTree::lct+x;
331     TopTree::lct[y].update();
332 };
333 
334 inline void TopTree::cut(int x,int y)
335 {
336     setroot(x);
337     access(TopTree::lct+y);
338     TopTree::lct_node *t=splay(TopTree::lct+y);
339     t->ch[0]->fa=NULL;t->ch[0]=NULL;
340     t->update();
341 };
342 
343 inline void TopTree::init(int *a)
344 {
345     int i;
346     for(i=1;i<=n;i++){
347         TopTree::lct[i].first=TopTree::lct[i].last=TopTree::lct+i;
348         TopTree::lct[i].x=TopTree::lct[i].sum=TopTree::lct[i].all=(Info){a[i],1,a[i]};
349         TopTree::lct[i].tree=NULL_INFO;
350         TopTree::lct[i].chain_tag=TopTree::lct[i].tree_tag=NULL_TAG;
351     };
352 };

 

转载于:https://www.cnblogs.com/chxer/p/4589622.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值