记录编号 |
248006 |
评测结果 |
AAAAAAAAAAAAAAAAAAAA |
题目名称 |
[国家集训队2012]tree(伍一鸣) |
最终得分 |
100 |
用户昵称 |
mikumikumi |
是否通过 |
通过 |
代码语言 |
C++ |
运行时间 |
14.977 s |
提交时间 |
2016-04-09 21:50:24 |
内存使用 |
3.56 MiB |
显示代码纯文本
- #include<cstdio>
- #include<iostream>
- #include<cmath>
- using namespace std;
- const int SIZEN=100010,MOD=51061;
- typedef long long LL;
- int N,M;
- class miku
- {
- public:
- int son[2],fa;
- unsigned int sum,val,add,mul,siz;
- bool rev;
- miku()
- {
- fa=son[0]=son[1]=0;
- val=sum=mul=siz=1;add=0;
- }
- #define sum(x) tr[x].sum
- #define val(x) tr[x].val
- #define mul(x) tr[x].mul
- #define siz(x) tr[x].siz
- #define rev(x) tr[x].rev
- #define add(x) tr[x].add
- #define fa(x) tr[x].fa
- #define ls(x) tr[x].son[0]
- #define rs(x) tr[x].son[1]
- }tr[SIZEN];
- void update(int x)
- {
- if(!x) return;
- sum(x)=(sum(ls(x))+sum(rs(x))+val(x))%MOD;
- siz(x)=siz(ls(x))+siz(rs(x))+1;
- }
- void Node_mul(int x,int t)
- {
- if(!x) return;
- sum(x)=(sum(x)*t)%MOD;
- add(x)=(add(x)*t)%MOD;
- val(x)=(val(x)*t)%MOD;
- mul(x)=(mul(x)*t)%MOD;
- }
- void Node_add(int x,int t)
- {
- if(!x) return;
- sum(x)=(sum(x)+t*siz(x))%MOD;
- val(x)=(val(x)+t)%MOD;
- add(x)=(add(x)+t)%MOD;
- }
- void pushdown(int x)
- {
- if(mul(x)!=1)
- {
- Node_mul(ls(x),mul(x));
- Node_mul(rs(x),mul(x));
- mul(x)=1;
- }
- if(add(x)!=0)
- {
- Node_add(ls(x),add(x));
- Node_add(rs(x),add(x));
- add(x)=0;
- }
- if(rev(x))
- {
- rev(x)^=1;
- swap(ls(x),rs(x));
- if(ls(x)) rev(ls(x))^=1;
- if(rs(x)) rev(rs(x))^=1;
- }
- }
- bool isroot(int x)
- {
- if(fa(x)==0) return 1;
- if(ls(fa(x))==x||rs(fa(x))==x) return 0;
- return 1;
- }
- void rotate(int x)
- {
- int y=tr[x].fa,z=tr[y].fa,l,r;
- if(tr[y].son[0]==x) l=0;
- else l=1;
- r=l^1;
- if(!isroot(y))
- {
- if(tr[z].son[0]==y) tr[z].son[0]=x;
- else tr[z].son[1]=x;
- }
- tr[tr[x].son[r]].fa=y;tr[x].fa=z;tr[y].fa=x;
- tr[y].son[l]=tr[x].son[r];tr[x].son[r]=y;
- update(y);update(x);
- }
- void splay(int x)
- {
- pushdown(x);
- while(!isroot(x))
- {
- int y=fa(x),z=fa(y);
- pushdown(z);pushdown(y);pushdown(x);
- if(!isroot(y))
- {
- if((tr[y].son[0]==x)^(tr[z].son[0]==y)) rotate(x);
- else rotate(y);
- }
- rotate(x);
- }
- }
- void access(int x)
- {
- int v=0;
- while(x)
- {
- splay(x);
- tr[x].son[1]=v;
- update(x);
- v=x;
- x=tr[x].fa;
- }
- }
- void make_root(int x)
- {
- access(x);
- splay(x);
- tr[x].rev^=1;
- }
- void link(int u,int v)
- {
- make_root(v);
- //splay(v);
- fa(v)=u;
- }
- void read()
- {
- scanf("%d%d",&N,&M);
- int fr,to;
- for(int i=1;i<N;i++)
- {
- scanf("%d%d",&fr,&to);
- link(fr,to);
- }
- }
- void Path_mul(int x,int y,int t)
- {
- make_root(x);
- access(y);
- splay(y);
- Node_mul(y,t);
- }
- void Path_add(int x,int y,int t)
- {
- make_root(x);
- access(y);
- splay(y);
- Node_add(y,t);
- }
- void cut(int x,int y)
- {
- make_root(x);
- access(y);
- splay(x);
- rs(x)=0;fa(y)=0;
- update(x);
- }
- int query(int x,int y)
- {
- make_root(x);
- access(y);
- splay(y);
- return sum(y);
- }
- void work()
- {
- char c;
- int fr,to,w;
- int u,v;
- for(int i=1;i<=M;i++)
- {
- while(true)
- {
- c=getchar();
- if(c!='\n'&&c!='\r') break;
- }
- //cout<<c<<endl;
- if(c=='*')
- {
- scanf("%d%d%d",&fr,&to,&w);
- Path_mul(fr,to,w);
- }
- if(c=='/')
- {
- scanf("%d%d",&fr,&to);
- int ans=query(fr,to);
- printf("%d\n",ans);
- }
- if(c=='+')
- {
- scanf("%d%d%d",&fr,&to,&w);
- Path_add(fr,to,w);
- }
- if(c=='-')
- {
- scanf("%d%d%d%d",&fr,&to,&u,&v);
- cut(fr,to);
- link(u,v);
- }
- }
- }
- int main()
- {
- freopen("nt2012_wym_tree.in","r",stdin);
- freopen("nt2012_wym_tree.out","w",stdout);
- tr[0].val=tr[0].sum=tr[0].add=tr[0].siz=0;
- read();
- work();
- return 0;
- }