【BZOJ】【P2631】【tree】【题解】【LCT】

来源:互联网 发布:ios编程软件 编辑:程序博客网 时间:2024/06/08 06:14

传送门: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);}elseif(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));}elseif(op=='*'){int u,v,c;scanf("%d%d%d",&u,&v,&c);LCT::mul(id(u),id(v),c%mo);}elseif(op=='/'){int u,v;scanf("%d%d",&u,&v);printf("%d\n",LCT::Qsum(id(u),id(v)));}}return 0;}


0 0
原创粉丝点击