BZOJ 2631: tree

题目链接:

  TP

题解:

  emmmm,刚掌握了$lazy-zag$,调了好久233

  一开始是因为直接让当前节点的$sum$等于两儿子之和,发现只出0,意识到还有本节点的价值……

  然后发现这样子还是不太对,意识到下传标记的时候不止要给儿子点权、$lazy$标记 乘/加 标记,还要给儿子的$sum$乘/加。

  然后还是不对……发现自己给儿子$sum$传$add$的时候没有乘儿子树的大小……

  终于过了……

代码:

  

  1 #define Troy
  2  
  3 #include "bits/stdc++.h"
  4  
  5 using namespace std;
  6  
  7 const int N=1e5+5,mod=51061;
  8  
  9 inline int read(){
 10     int s=0,k=1;char ch=getchar();
 11     while(ch<'0'|ch>'9')    ch=='-'?k=-1:0,ch=getchar();
 12     while(ch>47&ch<='9')    s=s*10+(ch^48),ch=getchar();
 13     return s*k;
 14 }
 15  
 16 #define size(t) (t?t->size:0)
 17 #define sz(t)   (t?t->sz:0)
 18 #define rev(t)  (t?t->rev^=1:0)
 19 #define mul(x,y)  (x*1ll*y>mod?x=x*1ll*y%mod:x=x*1ll*y)
 20 #define add(x,y)  (x=x+y,x>=mod?x-=mod:0)
 21  
 22 struct Node{
 23     Node *fa,*son[2];
 24     int sum,mul,add,rev,size,sz;
 25     Node(){fa=son[0]=son[1]=NULL;sum=size=mul=1,add=0,rev=0;}
 26     inline void update(){size=(sum*1ll+size(son[0])+size(son[1]));if(size>=mod) size%=mod;sz=1+sz(son[0])+sz(son[1]);}
 27     inline void pushdown(){
 28         if(rev){swap(son[0],son[1]);rev=0;
 29             rev(son[0]),rev(son[1]);
 30         }
 31         int t;
 32         if(son[0]){
 33             t=add*1ll*son[0]->sz%mod;
 34             mul(son[0]->size,mul),add(son[0]->size,t);
 35             mul(son[0]->sum,mul),add(son[0]->sum,add);
 36             mul(son[0]->mul,mul),mul(son[0]->add,mul);
 37             add(son[0]->add,add);
 38         }
 39         if(son[1]){
 40             t=add*1ll*son[1]->sz%mod;
 41             mul(son[1]->size,mul),add(son[1]->size,t);            
 42             mul(son[1]->sum,mul),add(son[1]->sum,add);
 43             mul(son[1]->mul,mul),mul(son[1]->add,mul);
 44             add(son[1]->add,add);
 45         }
 46         mul=1,add=0;
 47     }
 48 }*pool[N],*tmp[N],tree[N];int top;
 49  
 50 inline void init(){for(;top<N;++top)   pool[top]=tree+top;}
 51 inline void newNode(Node *&p,Node *f){p=pool[--top];*p=Node();p->fa=f;}
 52 inline void freeNode(Node *&p){pool[top++]=p,p=NULL;}
 53  
 54 int n,m;
 55 class LCT{
 56 public:
 57     Node *node[N];
 58     inline void init(int n){for(register int i=1;i<=n;++i)newNode(node[i],NULL);}
 59      
 60     #define son(p)  (p->fa->son[1]==p)
 61     #define is_root(p)  ((!p->fa)||(p->fa->son[0]!=p&&p->fa->son[1]!=p))
 62  
 63     inline void rotate(Node *p){
 64         int a=son(p)^1;Node *f=p->fa;
 65         f->son[a^1]=p->son[a];
 66         if(p->son[a])   p->son[a]->fa=f;
 67         p->fa=f->fa;
 68         if(!is_root(f))   p->fa->son[son(f)]=p;
 69         f->fa=p,p->son[a]=f,f->update(),p->update();
 70     }
 71  
 72     inline void splay(Node *&p){
 73         register int pos=0;
 74         for(Node *t=p;;t=t->fa){
 75             tmp[++pos]=t;
 76             if(is_root(t)) break;
 77         }
 78         for(;pos;--pos) tmp[pos]->pushdown();
 79         for(;!is_root(p);rotate(p))
 80             if(!is_root(p->fa)) rotate(son(p)==son(p->fa)?p->fa:p);
 81     }
 82  
 83     inline void access(Node *p){
 84         for(Node *pre=NULL;p;pre=p,p=p->fa)
 85             splay(p),p->son[1]=pre,p->update();
 86     }
 87  
 88     #define make_root(p) (access(p),splay(p),rev(p))
 89     #define mas(x,y) (make_root(x),access(y),splay(y))
 90  
 91     inline void cut(Node *x,Node *y){mas(x,y);x->fa=y->son[0]=NULL,y->update();} 
 92     inline void link(Node *x,Node *y){if(x->fa) swap(x,y);make_root(x),x->fa=y;}
 93     inline void link(int x,int y){link(node[x],node[y]);}
 94  
 95     inline void op_era(int x,int y,int nx,int ny){cut(node[x],node[y]),link(node[nx],node[ny]);}
 96     inline void op_plus(int x,int y,int val){
 97         mas(node[x],node[y]);
 98         add(node[y]->sum,val);
 99         add(node[y]->add,val);
100     }
101     inline void op_mul(int x,int y,int val){            
102         mas(node[x],node[y]);        
103         mul(node[y]->sum,val),mul(node[y]->mul,val);
104         mul(node[y]->add,val);
105     }
106      
107     inline void op_del(int x,int y){
108         mas(node[x],node[y]); 
109         printf("%d\n",node[y]->size);
110     }
111 }lct;
112  
113 int main(){
114     // freopen(".in","r",stdin);
115     // freopen(".out","w",stdout);
116     n=read(),m=read();
117     init();
118     lct.init(n);
119     register int i,x,y,nx,ny;
120     for(i=1;i^n;++i){
121         x=read(),y=read();
122         lct.link(x,y);
123     }
124     char opt[3];
125     while(m--){
126         scanf("%s",opt);x=read(),y=read();
127         switch(opt[0]){
128             case '*':lct.op_mul(x,y,read()%mod); break;
129             case '+':lct.op_plus(x,y,read()%mod);break;
130             case '-':nx=read(),ny=read();lct.op_era(x,y,nx,ny);break;
131             case '/':lct.op_del(x,y);break;
132         }
133     }
134 }

 

posted @ 2017-12-16 08:14  Troywar  阅读(177)  评论(0编辑  收藏  举报