bzoj2631 tree
来源:互联网 发布:淘宝网晚礼服图片 编辑:程序博客网 时间:2024/05/30 22:45
也算填了一个坑吧。。。以前用线段树就不会搞这个混合加乘的操作。。。
而且都开long long 就超时了,换成unsigned int
/************************************************************** Problem: 2631 User: Clare Language: C++ Result: Accepted Time:16420 ms Memory:5016 kb****************************************************************/ #include <cstdio>#include <iostream>#include <algorithm>#include <cstring>#include <cmath>#include <queue>#include <stack>#include <vector>using namespace std; #define N 100010#define INF 0x7fffffff#define Mod 51061typedef unsigned int ll; int n,m,q;int fa[N],c[N][2],next[N],size[N];ll sum[N],v[N],flag[N],flag1[N];bool Rev[N];char S[5];stack<int> st; inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();} return x*f;} bool Pd_root(int k){ return !(c[fa[k]][0]==k)&&!(c[fa[k]][1]==k);} void Pushup(int k){ int l=c[k][0],r=c[k][1]; size[k]=size[l]+size[r]+1; sum[k]=(sum[r]+sum[l]+v[k])%Mod;} void Cal(int k,ll mul,ll add){ if(!k) return; v[k]=(v[k]*mul+add)%Mod; sum[k]=(sum[k]*mul+add*size[k])%Mod; flag[k]=flag[k]*mul%Mod; flag1[k]=(flag1[k]*mul+add)%Mod;} void Pushdown(int k){ int l=c[k][0],r=c[k][1]; if(Rev[k]) { Rev[k]^=1;Rev[r]^=1;Rev[l]^=1; swap(c[k][0],c[k][1]); } Cal(l,flag[k],flag1[k]); Cal(r,flag[k],flag1[k]); flag[k]=1;flag1[k]=0;} void Rotate(int x){ int y=fa[x],z=fa[y],l,r; if(c[y][0]==x)l=0;else l=1;r=l^1; if(Pd_root(y)); else if(c[z][0]==y)c[z][0]=x; else c[z][1]=x; fa[x]=z;fa[y]=x;fa[c[x][r]]=y; c[y][l]=c[x][r];c[x][r]=y; Pushup(y);Pushup(x);} void Splay(int x){ int i=x; for(i=x;!Pd_root(i);i=fa[i]) st.push(i); st.push(i); while(!st.empty()) { int now=st.top();st.pop(); Pushdown(now); } while(!Pd_root(x)) { int y=fa[x],z=fa[y]; if(!Pd_root(y)) { if(c[z][0]==y^c[y][0]==x) Rotate(x); else Rotate(y); } Rotate(x); }} void Access(int x){ for(int t=0;x;t=x,x=fa[x]) Splay(x),c[x][1]=t,Pushup(x);} void Move_to_root(int x){ Access(x);Splay(x);Rev[x]^=1;} void Join(int x,int y){ Move_to_root(x);fa[x]=y;Splay(x);} void Cut(int x,int y){ Move_to_root(x);Access(y);Splay(y); if(x==c[y][0]) c[y][0]=fa[x]=0; else c[y][1]=fa[x]=0; Pushup(y);Pushup(x);} void Split(int x,int y){ Move_to_root(x);Access(y);Splay(y);} int main(){ n=read();q=read(); for(int i=1;i<=n;i++) v[i]=sum[i]=size[i]=flag[i]=1; for(int i=1;i<=n-1;i++) { int x=read(),y=read(); Join(x,y); } while(q--) { scanf("%s",S); if(S[0]=='+') { int x=read(),y=read(),val=read(); Split(x,y);Cal(y,1,val); } else if(S[0]=='*') { int x=read(),y=read(),val=read(); Split(x,y);Cal(y,val,0); } else if(S[0]=='-') { int x1=read(),y1=read(),x2=read(),y2=read(); Cut(x1,y1);Join(x2,y2); } else { int x=read(),y=read(); Split(x,y); printf("%d\n",sum[y]); } } return 0;}
0 0
- bzoj2631 tree
- bzoj2631: tree
- 【BZOJ2631】tree
- bzoj2631 tree
- [BZOJ2631] tree
- [BZOJ2631]tree
- BZOJ2631: tree
- bzoj2631: tree
- Bzoj2631 Tree
- bzoj2631 tree
- BZOJ2631: tree
- 【bzoj2631】tree
- bzoj2631 tree
- 【bzoj2631】tree
- 【BZOJ2631】tree
- bzoj2631: tree
- bzoj2631 tree(伍一鸣)
- bzoj2631: tree LCT
- 在C#应用中使用Matlab函数
- tar加减号时的作用 tar cf - | tar xf - 管道 linux
- Android 开发 调用图库选择图片实现和参数详解
- Restful Web Services
- 制作ubuntu的盘启动盘
- bzoj2631 tree
- php线程
- Linux下Socket编程之read、write、send、recv函数的比较
- Android开发 调用照相机实现代码和注意事项
- linux下TCP/IP实现简单聊天程序
- android空指针异常
- Android桌面悬浮窗进阶,QQ手机管家小火箭效果实现
- 毕业季不悔
- bzoj2002 弹飞绵羊