欢迎光临
我们一直在努力

PLCT检查是什么[国家集训队]Tree II

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll p=51061;
const int N=1e5+10;

int c[N][2],f[N],st[N];//st为栈
ll v[N],sz[N],sum[N],add[N],mul[N];
bool r[N];

inline bool nroot(int x){//判断节点是否为所在Splay的根
    return c[f[x]][0]==x||c[f[x]][1]==x;
}//原理:如果是根则是父亲的儿子没有x节点
inline void pushup(int x){
    sz[x]=sz[c[x][0]]+sz[c[x][1]]+1;
    sum[x]=((sum[c[x][0]]+sum[c[x][1]])*mul[x]%p+(sz[x]-1)*add[x]%p+v[x])%p;
}
inline void pushadd(int x,int c){
    add[x]=(add[x]+c)%p;
    v[x]=(v[x]+c)%p;
    sum[x]=(sum[x]+sz[x]*c)%p;
}
inline void pushmul(int x,int c){
    add[x]=(add[x]*c)%p;
    mul[x]=(mul[x]*c)%p;
    v[x]=(v[x]*c)%p;
    sum[x]=(sum[x]*c)%p;
}
inline void pushr(int x){
    r[x]^=1;
    swap(c[x][0],c[x][1]);
}
inline void pushdown(int x)
    if(mul[x]!=1)
    if(add[x])
}
void rotate(int x)
void splay(int x)
    pushup(x);
}
void access(int x){//拉出树根到x的链到一个Splay
    for(int y=0;x;x=f[y=x])
        splay(x),c[x][1]=y,pushup(x);//删链所以pushup
}
void makeroot(int x){//换x为原树根
    access(x);splay(x);
    pushr(x);
}
int findroot(int x){//找x在原树中的根
    access(x);splay(x);
    while(c[x][0])pushdown(x),x=c[x][0];
    splay(x);//??
    return x;
}
void split(int x,int y){//拉出x-y链到一个Splay
    makeroot(x);
    access(y);splay(y);
}
void link(int x,int y)
void cut(int x,int y)
}
int main(){
    int n,q,x,y,x2,y2,c;
    scanf("%d%d",&n,&q);
    for(int i=1;i<=n;++i)mul[i]=v[i]=1;//sz,sum省略
    for(int i=1;i<n;++i){
        scanf("%d%d",&x,&y);
        link(x,y);
    }
    while(q--)else if(op=='-'){
            scanf("%d%d%d%d",&x,&y,&x2,&y2);
            cut(x,y);link(x2,y2);
        }else if(op=='*'){
            scanf("%d%d%d",&x,&y,&c);
            split(x,y);
            pushmul(y,c);
        }else if(op=='/'){
            scanf("%d%d",&x,&y);
            split(x,y);
            printf("%lld
",sum[y]);
        }
    }
    return 0;
}
赞(0)
未经允许不得转载:上海聚慕医疗器械有限公司 » PLCT检查是什么[国家集训队]Tree II

登录

找回密码

注册