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

王学长的LCT标程

时间:2015-05-19 00:25:36      阅读:278      评论:0      收藏:0      [点我收藏+]

标签:

善良的王学长竟然亲自打了一遍QAQ好感动QAQ

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cmath>
  4 #include<algorithm>
  5 #include<queue>
  6 #include<cstring>
  7 #define PAU putchar(‘ ‘)
  8 #define ENT putchar(‘\n‘)
  9 using namespace std;
 10 const int maxn=100000+10;
 11 inline int read(){
 12     int x=0,sig=1;char ch=getchar();
 13     while(!isdigit(ch)){if(ch==-)sig=-1;ch=getchar();}
 14     while(isdigit(ch))x=10*x+ch-0,ch=getchar();
 15     return x*=sig;
 16 }
 17 inline void write(int x){
 18     if(x==0){putchar(0);return;}if(x<0)putchar(-),x=-x;
 19     int len=0,buf[15];while(x)buf[len++]=x%10,x/=10;
 20     for(int i=len-1;i>=0;i--)putchar(buf[i]+0);return;
 21 }
 22 struct node {
 23     node *ch[2],*fa;
 24     bool rev;
 25     int x,sum,siz,mul,add;
 26     inline void add_rev_tag(){
 27         swap(ch[0],ch[1]);rev^=1;return;
 28     }
 29     inline void add_plus_tag(int a){
 30         sum+=siz*a;x+=a;add+=a;return;
 31     }
 32     inline void add_mul_tag(int m){
 33         sum*=m;x*=m;mul*=m;add*=add*m;return;
 34     }
 35     inline void down(){
 36         if(rev){
 37             if(ch[0]) ch[0]->add_rev_tag();
 38             if(ch[1]) ch[1]->add_rev_tag();
 39             rev=0;
 40         }
 41         if(add){
 42             if(ch[0]) ch[0]->add_plus_tag(add);
 43             if(ch[1]) ch[1]->add_plus_tag(add);
 44             add=0;
 45         }
 46         if(mul>1){
 47             if(ch[0]) ch[0]->add_mul_tag(mul);
 48             if(ch[1]) ch[1]->add_mul_tag(mul);
 49             mul=1;
 50         } return;
 51     }
 52     inline void update(){
 53         sum=x;siz=1;
 54         if(ch[0]) sum+=ch[0]->sum,siz+=ch[0]->siz;
 55         if(ch[1]) sum+=ch[1]->sum,siz+=ch[1]->siz;
 56         return;
 57     }
 58 }lct[maxn];
 59 inline int get_parent(node *x,node *&fa){return (fa=x->fa)?fa->ch[0]==x?0:fa->ch[1]==x?1:-1:-1;}
 60 inline void rotate(node *x){
 61     int t1,t2;
 62     node *fa,*gfa;
 63     t1=get_parent(x,fa);
 64     t2=get_parent(fa,gfa);
 65     if ((fa->ch[t1]=x->ch[t1^1])) fa->ch[t1]->fa=fa;
 66     x->ch[t1^1]=fa;fa->fa=x;x->fa=gfa;
 67     if (t2!=-1) gfa->ch[t2]=x;
 68     fa->update();return;
 69 }
 70 inline void pushdown(node *x){
 71     static node *stack[maxn];
 72     int cnt=0;
 73     while(1){
 74         stack[cnt++]=x;
 75         node *fa=x->fa;
 76         if (!fa || (fa->ch[0]!=x && fa->ch[1]!=x)) break;
 77         x=fa;
 78     }
 79     while(cnt--) stack[cnt]->down();
 80     return;
 81 }
 82 inline node * splay(node *x){
 83     pushdown(x);
 84     while(1){
 85         int t1,t2;
 86         node *fa,*gfa;
 87         t1=get_parent(x,fa);
 88         if(t1==-1) break;
 89         t2=get_parent(fa,gfa);
 90         if(t2==-1){
 91             rotate(x);break;
 92         } else if (t1==t2){
 93             rotate(fa);rotate(x);
 94         } else{
 95             rotate(x);rotate(x);
 96         }
 97     }
 98     x->update();
 99     return x;
100 }
101 inline node * access(node *x){
102     node *ret=NULL;
103     while (x) splay(x)->ch[1]=ret,(ret=x)->update(),x=x->fa;
104     return ret;
105 }
106 inline void makeroot(int x){access(lct+x)->add_rev_tag();}
107 inline void link(int u,int v){
108     makeroot(u);splay(lct+u)->fa=lct+v;return;
109 }
110 inline void cut(int u,int v){
111     makeroot(u);
112     node *p=(access(lct+v),splay(lct+v));
113     p->ch[0]->fa=NULL;
114     p->ch[0]=NULL;
115     p->update();
116 }
117 int n,q;
118 int main(){
119     n=read();q=read();
120     int i;
121     for(i=1;i<=n;i++) {
122         lct[i].x=lct[i].sum=1;
123         lct[i].siz=1;
124         lct[i].mul=1;
125     }
126     for(i=1;i<n;i++){
127         int u,v;
128         u=read();v=read();
129         link(u,v);
130     }
131     while(q--){
132         char ch=getchar();
133         while(ch<=32) ch=getchar();
134         int u,v,x,y,c;
135         if(ch==+){
136             u=read();v=read();c=read();
137             makeroot(u);
138             access(lct+v)->add_plus_tag(c);
139         }else if(ch==-){
140             u=read();v=read();x=read();y=read();
141             cut(u,v);link(x,y);
142         }else if(ch==*){
143             u=read();v=read();c=read();
144             makeroot(u);
145             access(lct+v)->add_mul_tag(c);
146         }else if(ch==/){
147             u=read();v=read();
148             makeroot(u);
149             printf("%u\n",access(lct+v)->sum);
150         }
151     }
152     return 0;
153 }

 

王学长的LCT标程

标签:

原文地址:http://www.cnblogs.com/chxer/p/4513320.html

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