考虑ADD对SUM的影响的时候要乘上SIZE.
/* I will wait for you */ #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<ctime> #include<algorithm> #include<iostream> #include<fstream> #include<vector> #include<queue> #include<deque> #include<set> #include<map> #include<string> typedef long long LL; typedef unsigned long long ULL; typedef unsigned int Uint; using namespace std; const int maxn=1000010; const int maxm=1010; const int maxs=26; const int INF=1<<29; const int P=51061; const double error=1e-9; struct node { Uint sum,key,rev,add,mul,size; node *fa,*son[2]; int isroot() { return !fa||this!=fa->son[0]&&this!=fa->son[1]; }; int dir() { return this==fa->son[1]; }; }no[maxn]; inline void pushdown(node* o) { if(o->mul!=1) { for(int i=0;i<2;i++) if(o->son[i]) (o->son[i]->mul*=o->mul)%=P,(o->son[i]->add*=o->mul)%=P; (o->key*=o->mul)%=P;(o->sum*=o->mul)%=P;o->mul=1; } if(o->add) { for(int i=0;i<2;i++) if(o->son[i]) (o->son[i]->add+=o->add)%=P; (o->key+=o->add)%=P;(o->sum+=o->add*o->size)%=P;o->add=0; } if(o->rev) { for(int i=0;i<2;i++) if(o->son[i]) o->son[i]->rev^=1; swap(o->son[0],o->son[1]);o->rev=0; } } inline void maintain(node* o) { o->sum=o->key;o->size=1; for(int i=0;i<2;i++) if(o->son[i]) { pushdown(o->son[i]); o->son[i]->fa=o; o->size+=o->son[i]->size; (o->sum+=o->son[i]->sum)%=P; } } inline void rotate(node* o) { node* p=o->fa; pushdown(p);pushdown(o); int d=o->dir(); p->son[d]=o->son[d^1]; o->son[d^1]=p;o->fa=p->fa; if(!p->isroot()) p->fa->son[p->dir()]=o; maintain(p);maintain(o); } inline void splay(node* o) { pushdown(o); while(!o->isroot()) { node* p=o->fa; if(p->isroot()) rotate(o); else if(o->dir()==p->dir()) rotate(p),rotate(o); else rotate(o),rotate(o); } } inline void access(node* o) { for(node* t=0;o;t=o,o=o->fa) splay(o),o->son[1]=t,maintain(o); } inline void evert(node* o) { access(o);splay(o);o->rev^=1; } inline void link(node* u,node* v) { evert(u);u->fa=v; } inline void cut(node* u,node* v) { evert(u);access(v);splay(v);u->fa=v->son[0]=0; } inline void qsum(node* u,node* v) { evert(u);access(v);splay(v);pushdown(v);cout<<v->sum<<'\n'; } inline void make(node& o,Uint k) { o.sum=o.key=k;o.add=o.rev=0;o.mul=o.size=1; o.fa=o.son[0]=o.son[1]=0; } inline void add(node* u,node* v,Uint c) { evert(u);access(v);splay(v);pushdown(v);v->add=c; } inline void mul(node* u,node* v,Uint c) { evert(u);access(v);splay(v);pushdown(v);v->mul=c; } int main() { int n,m;scanf("%d%d",&n,&m); for(int i=1,k;i<=n;i++) make(no[i],(Uint)1); for(int i=1,u,v;i<n;i++) scanf("%d%d",&u,&v),link(&no[u],&no[v]); for(int i=0;i<m;i++) { char s[10];int x,y,u,v,c;scanf("%s%d%d",&s,&x,&y); if(s[0]=='+') scanf("%d",&c),add(&no[x],&no[y],(Uint)c); if(s[0]=='*') scanf("%d",&c),mul(&no[x],&no[y],(Uint)c); if(s[0]=='-') scanf("%d%d",&u,&v),cut(&no[x],&no[y]),link(&no[u],&no[v]); if(s[0]=='/') qsum(&no[x],&no[y]); } return 0; }