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
原创粉丝点击