传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2631
裸题
Code:
#include<bits/stdc++.h>
#define id(x) (LCT::pool+x)
using namespace std;
typedef long long LL;
const int maxn=1e5+5;
int mo=51061,n,m;
namespace LCT{
struct node{
int rev,val,mul,add,size,sum;
node *c[2],*p;
void makerev(){rev^=1;swap(c[0],c[1]);}
void pd(){
if(rev){rev=0;c[0]->makerev();c[1]->makerev();}
if(mul==1&&!add)return;
c[0]->val=((LL)c[0]->val*mul%mo+add)%mo;
c[0]->sum=((LL)c[0]->sum*mul%mo+(LL)c[0]->size*add%mo)%mo;
c[0]->mul=((LL)c[0]->mul*mul%mo)%mo;
c[0]->add=((LL)c[0]->add*mul%mo+add)%mo;
c[1]->val=((LL)c[1]->val*mul%mo+add)%mo;
c[1]->sum=((LL)c[1]->sum*mul%mo+(LL)c[1]->size*add%mo)%mo;
c[1]->mul=((LL)c[1]->mul*mul%mo)%mo;
c[1]->add=((LL)c[1]->add*mul%mo+add)%mo;
mul=1;add=0;
}
void rz(){
sum=(c[0]->sum+val+c[1]->sum)%mo;
size=c[0]->size+1+c[1]->size;
}
void sets(node *x,int d){pd();(c[d]=x)->p=this;rz();}
bool d(){return p->c[1]==this;}
bool rt(){return p->c[0]!=this&&p->c[1]!=this;}
}*null,pool[maxn];
node *newnode(int _val=0){
static node *x=pool;
x->rev=0;x->val=x->sum=_val;
x->mul=1;x->add=0;x->size=1;
x->c[0]=x->c[1]=x->p=null;
return x++;
}
void init(){
null=newnode();null->mul=0;null->size=0;
null->c[0]=null->c[1]=null->p=null;
for(int i=1;i<=n;i++)newnode(1);
}
void rot(node *x){
node *y=x->p;if(!y->rt())y->p->pd();
y->pd();x->pd();int d=x->d();
y->sets(x->c[!d],d);
if(y->rt())x->p=y->p;
else y->p->sets(x,y->d());
x->sets(y,!d);
}
void splay(node *x){
for(;!x->rt();rot(x))if(x->p->rt());
else if(x->d()==x->p->d())rot(x->p);
else rot(x);
}
node *access(node *x){
node *y=null;
for(;x!=null;x=x->p)splay(x),x->sets(y,1),y=x;
return y;
}
void makert(node *x){
access(x)->makerev();splay(x);
}
node *findrt(node *x){
for(x=access(x);x->pd(),x->c[0]!=null;x=x->c[0]);return x;
}
void link(node *x,node *y){
makert(x);x->p=y;access(x);
}
void cut(node *x,node *y){
makert(x);access(y);splay(y);
y->c[0]=x->p=null;y->rz();
}
int Qsum(node *x,node *y){
makert(x);access(y);splay(y);
return y->sum;
}
void add(node *x,node *y,int c){
makert(x);access(y);splay(y);
y->val=(y->val+c)%mo;
y->sum=(y->sum+(LL)y->size*c%mo)%mo;
y->add=(y->add+c)%mo;
}
void mul(node *x,node *y,int c){
makert(x);access(y);splay(y);
y->val=((LL)y->val*c)%mo;
y->sum=((LL)y->sum*c)%mo;
y->mul=((LL)y->mul*c)%mo;
y->add=((LL)y->add*c)%mo;
}
}
int main(){
scanf("%d%d",&n,&m);
LCT::init();
for(int i=1;i<n;i++){
int u,v;scanf("%d%d",&u,&v);
LCT::link(id(u),id(v));
}
while(m--){
char op=getchar();
while(op!='+'&&op!='-'&&op!='*'&&op!='/')op=getchar();
if(op=='+'){
int u,v,c;scanf("%d%d%d",&u,&v,&c);
LCT::add(id(u),id(v),c%mo);
}else
if(op=='-'){
int u1,v1,u2,v2;scanf("%d%d%d%d",&u1,&v1,&u2,&v2);
LCT::cut(id(u1),id(v1));
LCT::link(id(u2),id(v2));
}else
if(op=='*'){
int u,v,c;scanf("%d%d%d",&u,&v,&c);
LCT::mul(id(u),id(v),c%mo);
}else
if(op=='/'){
int u,v;scanf("%d%d",&u,&v);
printf("%d\n",LCT::Qsum(id(u),id(v)));
}
}
return 0;
}