bzoj2631 -- LCT

包含了link、cut、update、query操作。

更新时类似线段树就可以了。

代码:

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
#define N 100010
#define M 51061
#define ll unsigned int
inline char nc(){
    static char buf[100000],*p1=buf,*p2=buf;
    if(p1==p2){
        p2=(p1=buf)+fread(buf,1,100000,stdin);
        if(p1==p2)return EOF;
    }
    return *p1++;
}
inline void Read(int& x){
    char c=nc();
    for(;c<'0'||c>'9';c=nc());
    for(x=0;c>='0'&&c<='9';x=(x<<3)+(x<<1)+c-48,c=nc());
}
inline void Read(char& C){
    char c=nc();
    for(;c!='+'&&c!='*'&&c!='-'&&c!='/';c=nc());
    C=c;
}
int Len;
char S[30];
inline void Print(ll x){
    if(x==0)putchar(48);
    for(Len=0;x;x/=10)S[++Len]=x%10;
    for(;Len;)putchar(S[Len--]+48);putchar('\n');
}
int i,j,k,n,m,Q,f[N],h[N],ch[N][2],x,y,z,s[N];
ll Sum[N],p1[N],p2[N],a[N];
bool b[N],r[N];
char C;
inline int Get(int x){return ch[f[x]][1]==x;}
inline void Update_rev(int x){
    if(x==0)return;
    r[x]^=1;swap(ch[x][0],ch[x][1]);
}
inline void Update_mul(int x,int y){
    Sum[x]=(Sum[x]*y)%M;a[x]=(a[x]*y)%M;p1[x]=(p1[x]*y)%M;p2[x]=(p2[x]*y)%M;
}
inline void Update_add(int x,int y){
    Sum[x]=(Sum[x]+y*s[x])%M;a[x]=(a[x]+y)%M;p2[x]=(p2[x]+y)%M;
}
inline void Pushdown(int x){
    if(r[x]){
        Update_rev(ch[x][0]);
        Update_rev(ch[x][1]);
        r[x]=0;
    }
    if(p1[x]!=1){
        Update_mul(ch[x][0],p1[x]);
        Update_mul(ch[x][1],p1[x]);
        p1[x]=1;
    }
    if(p2[x]){
        Update_add(ch[x][0],p2[x]);
        Update_add(ch[x][1],p2[x]);
        p2[x]=0;
    }
}
inline void Pushup(int x){
    Sum[x]=(Sum[ch[x][0]]+Sum[ch[x][1]]+a[x])%M;
    s[x]=s[ch[x][0]]+s[ch[x][1]]+1;
}
inline void Rotate(int x){
    int y=f[x];bool d=Get(x);
    if(b[y])b[y]=0,b[x]=1;else ch[f[y]][Get(y)]=x;
    ch[y][d]=ch[x][d^1];f[ch[y][d]]=y;
    ch[x][d^1]=y;f[x]=f[y];f[y]=x;
    Pushup(y);
}
inline void P(int x){if(!b[x])P(f[x]);Pushdown(x);}
inline void Splay(int x){
    for(P(x);!b[x];Rotate(x))
    if(!b[f[x]])Rotate(Get(x)==Get(f[x])?f[x]:x);
    Pushup(x);
}
inline void Access(int x){
    int y=0;
    while(x){
        Splay(x);
        b[ch[x][1]]=1;ch[x][1]=y;b[y]=0;
        Pushup(y=x);x=f[x];
    }
}
inline void mr(int x){Access(x);Splay(x);Update_rev(x);}
inline void Link(int x,int y){mr(x);f[x]=y;}
inline void Update_Add(int x,int y,int z){
    mr(x);Access(y);Splay(y);
    Update_add(y,z);
}
inline void Update_Mul(int x,int y,int z){
    mr(x);Access(y);Splay(y);
    Update_mul(y,z);
}
inline void Del(int x,int y){
    mr(x);Access(y);Splay(y);
    f[x]=ch[y][0]=0;b[x]=1;Pushup(y);
}
inline ll Query(int x,int y){
    mr(x);Access(y);Splay(y);
    return Sum[y];
}
int main()
{
    Read(n);Read(Q);
    for(i=1;i<=n;i++)a[i]=b[i]=Sum[i]=s[i]=p1[i]=1;
    for(i=1;i<n;i++)Read(x),Read(y),Link(x,y);
    while(Q--){
        Read(C);
        if(C=='+')Read(x),Read(y),Read(z),Update_Add(x,y,z);else
        if(C=='-')Read(x),Read(y),Del(x,y),Read(x),Read(y),Link(x,y);else
        if(C=='*')Read(x),Read(y),Read(z),Update_Mul(x,y,z);else Read(x),Read(y),Print(Query(x,y));
    }
    return 0;
}
bzoj2631

 

posted @ 2017-03-16 08:49  gjghfd  阅读(131)  评论(0编辑  收藏  举报