ccz181078

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: :: 管理 ::

Description

 一棵n个点的树,每个点的初始权值为1。对于这棵树有q个操作,每个操作为以下四种操作之一:
+ u v c:将u到v的路径上的点的权值都加上自然数c;
- u1 v1 u2 v2:将树中原有的边(u1,v1)删除,加入一条新边(u2,v2),保证操作完之后仍然是一棵树;
* u v c:将u到v的路径上的点的权值都乘上自然数c;
/ u v:询问u到v的路径上的点的权值和,求出答案对于51061的余数。

Input

  第一行两个整数n,q
接下来n-1行每行两个正整数u,v,描述这棵树
接下来q行,每行描述一个操作

Output

  对于每个/对应的答案输出一行
lct模板题。。
#include<cstdio>
#include<algorithm>
typedef unsigned int u32;
const int P=51061;
char buf[10000007],*ptr=buf-1;
int _(){
    int x=0,c=*++ptr;
    while(c<48)c=*++ptr;
    while(c>47)x=x*10+c-48,c=*++ptr;
    return x;
}
int _c(){
    int c=*++ptr;
    while(c<33)c=*++ptr;
    return c;
}
#define lc ch][0
#define rc ch][1
#define fa ch][2
#define rev ch][3
#define K ch][4
#define B ch][5
#define sum ch][6
#define val ch][7
#define sz ch][8
u32 ch[100007][9];
int n,q;
void revs(u32 x){
    if(!x)return;
    x[rev]^=1;
    std::swap(x[lc],x[rc]);
}
void adds(u32 x,u32 a){
    if(!x)return;
    x[B]=(x[B]+a)%P;
    x[val]=(x[val]+a)%P;
    x[sum]=(x[sum]+a*x[sz])%P;
}
void muls(u32 x,u32 a){
    if(!x)return;
    x[K]=x[K]*a%P;
    x[B]=x[B]*a%P;
    x[val]=x[val]*a%P;
    x[sum]=x[sum]*a%P;
}
void dn(u32 x){
    u32 l=x[lc],r=x[rc];
    if(x[rev])revs(l),revs(r),x[rev]=0;
    if(x[K]!=1)muls(l,x[K]),muls(r,x[K]),x[K]=1;
    if(x[B])adds(l,x[B]),adds(r,x[B]),x[B]=0;
}
void up(u32 x){
    u32 l=x[lc],r=x[rc];
    x[sum]=(l[sum]+r[sum]+x[val])%P;
    x[sz]=(l[sz]+r[sz]+1)%P;
}
bool nrt(u32 x){
    return x==x[fa][lc]||x==x[fa][rc];
}
void rot(u32 x){
    u32 f=x[fa],g=f[fa],d=(x==f[rc]);
    dn(f),dn(x);
    if(nrt(f))g[ch][g[rc]==f]=x;
    x[fa]=g;
    (f[ch][d]=x[ch][d^1])[fa]=f;
    (x[ch][d^1]=f)[fa]=x;
    up(f),up(x);
}
void sp(u32 x){
    while(nrt(x)){
        int f=x[fa];
        if(nrt(f))rot((x==f[lc])==(f==f[fa][lc])?f:x);
        rot(x);
    }
}
int acs(u32 x){u32 y=0;for(;x;sp(x),dn(x),x[rc]=y,up(x),y=x,x=x[fa]);return y;}
void mrt(u32 x){revs(acs(x));}
void lk(u32 x,u32 y){mrt(x);sp(x);x[fa]=y;}
void ct(u32 x,u32 y){mrt(x);acs(y);sp(y);dn(y),x[fa]=y[lc]=0,up(y);}
int get(u32 x,u32 y){mrt(x);return acs(y);}
int main(){
    buf[fread(buf,1,sizeof(buf),stdin)]=0;
    n=_();q=_();
    for(int i=1;i<=n;++i)i[K]=i[sum]=i[sz]=i[val]=1;
    for(int i=1,a,b;i<n;++i){
        a=_();b=_();
        lk(a,b);
    }
    while(q--){
        int o=_c(),x;
        if(o=='+'){
            x=get(_(),_());adds(x,_());
        }else if(o=='-'){
            ct(_(),_());lk(_(),_());
        }else if(o=='*'){
            x=get(_(),_());muls(x,_());
        }else{
            x=get(_(),_());printf("%d\n",x[sum]);
        }
    }
    return 0;
}

 

posted on 2017-02-26 21:37  nul  阅读(198)  评论(0编辑  收藏  举报