题目链接:
题解:
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 }