#include<bits/stdc++.h> using namespace std; typedef long long ll; const ll p=51061; const int N=1e5+10; int c[N][2],f[N],st[N];//st为栈 ll v[N],sz[N],sum[N],add[N],mul[N]; bool r[N]; inline bool nroot(int x){//判断节点是否为所在Splay的根 return c[f[x]][0]==x||c[f[x]][1]==x; }//原理:如果是根则是父亲的儿子没有x节点 inline void pushup(int x){ sz[x]=sz[c[x][0]]+sz[c[x][1]]+1; sum[x]=((sum[c[x][0]]+sum[c[x][1]])*mul[x]%p+(sz[x]-1)*add[x]%p+v[x])%p; } inline void pushadd(int x,int c){ add[x]=(add[x]+c)%p; v[x]=(v[x]+c)%p; sum[x]=(sum[x]+sz[x]*c)%p; } inline void pushmul(int x,int c){ add[x]=(add[x]*c)%p; mul[x]=(mul[x]*c)%p; v[x]=(v[x]*c)%p; sum[x]=(sum[x]*c)%p; } inline void pushr(int x){ r[x]^=1; swap(c[x][0],c[x][1]); } inline void pushdown(int x) if(mul[x]!=1) if(add[x]) } void rotate(int x) void splay(int x) pushup(x); } void access(int x){//拉出树根到x的链到一个Splay for(int y=0;x;x=f[y=x]) splay(x),c[x][1]=y,pushup(x);//删链所以pushup } void makeroot(int x){//换x为原树根 access(x);splay(x); pushr(x); } int findroot(int x){//找x在原树中的根 access(x);splay(x); while(c[x][0])pushdown(x),x=c[x][0]; splay(x);//?? return x; } void split(int x,int y){//拉出x-y链到一个Splay makeroot(x); access(y);splay(y); } void link(int x,int y) void cut(int x,int y) } int main(){ int n,q,x,y,x2,y2,c; scanf("%d%d",&n,&q); for(int i=1;i<=n;++i)mul[i]=v[i]=1;//sz,sum省略 for(int i=1;i<n;++i){ scanf("%d%d",&x,&y); link(x,y); } while(q--)else if(op=='-'){ scanf("%d%d%d%d",&x,&y,&x2,&y2); cut(x,y);link(x2,y2); }else if(op=='*'){ scanf("%d%d%d",&x,&y,&c); split(x,y); pushmul(y,c); }else if(op=='/'){ scanf("%d%d",&x,&y); split(x,y); printf("%lld ",sum[y]); } } return 0; }
PLCT检查是什么[国家集训队]Tree II
未经允许不得转载:上海聚慕医疗器械有限公司 » PLCT检查是什么[国家集训队]Tree II









