[国家集训队]Tree II

LCT板子题。

和线段树2的操作方法一样,先乘后加就行了。洛谷评分虚高

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N=100005,mod=51061;
int n,q,ch[N][2],fa[N];long long val[N];long long siz[N];
long long sum[N],add[N],mul[N];
bool rev[N];
bool is_rt(int x){return x!=ch[fa[x]][0]&&x!=ch[fa[x]][1];}
bool ck(int x) {return x==ch[fa[x]][1];}
void pushup(int x) {
    siz[x]=siz[ch[x][1]]+siz[ch[x][0]]+1;
    sum[x]=(sum[ch[x][0]]+sum[ch[x][1]]+val[x])%mod;
}
void pushdown(int x) {
    if(mul[x]!=1) {
        if(ch[x][1])
            (sum[ch[x][1]]*=mul[x])%=mod,
            (val[ch[x][1]]*=mul[x])%=mod,
            (add[ch[x][1]]*=mul[x])%=mod,
            (mul[ch[x][1]]*=mul[x])%=mod;
        if(ch[x][0])
            (sum[ch[x][0]]*=mul[x])%=mod,
            (val[ch[x][0]]*=mul[x])%=mod,
            (add[ch[x][0]]*=mul[x])%=mod,
            (mul[ch[x][0]]*=mul[x])%=mod;
        mul[x]=1;
    }
    if(add[x]) {
        if(ch[x][0])
            (sum[ch[x][0]]+=add[x]*siz[ch[x][0]])%=mod,
            (val[ch[x][0]]+=add[x])%=mod,
            (add[ch[x][0]]+=add[x])%=mod;
        if(ch[x][1])
            (sum[ch[x][1]]+=add[x]*siz[ch[x][1]])%=mod,
            (val[ch[x][1]]+=add[x])%=mod,
            (add[ch[x][1]]+=add[x])%=mod;
        add[x]=0;
    }
    if(rev[x]) {
        swap(ch[x][0],ch[x][1]);
        rev[ch[x][0]]^=1;rev[ch[x][1]]^=1;
        rev[x]=0;
    }
}

void rotate(int x) {
    int f=fa[x],ff=fa[f];
    if(!is_rt(f)) ch[ff][ck(f)]=x;
    bool tag=ck(x);
    ch[f][tag]=ch[x][tag^1];
    fa[ch[f][tag]]=f;
    ch[x][tag^1]=f;
    fa[f]=x;
    fa[x]=ff;
    pushup(f);pushup(x);
}
int stk[N],top;
void splay(int x) {
    stk[top=1]=x;
    for(int i=x;!is_rt(i);i=fa[i]) stk[++top]=fa[i];
    for(int i=top;i;i--) pushdown(stk[i]);
    for(int f;!is_rt(x);rotate(x)) {
        if(!is_rt(f=fa[x])) rotate(ck(f)==ck(x)?f:x);
    }
}
void access(int x) {
    for(int t=0;x;t=x,x=fa[x]) {
        splay(x);ch[x][1]=t;pushup(x);
    }
}
void makeroot(int x) {
    access(x);
    splay(x);
    rev[x]^=1;
}
void link(int x,int y) {
    makeroot(x);
    fa[x]=y;
}
void cut(int x,int y) {
    makeroot(x);access(y);splay(y);
    ch[y][0]=fa[x]=0;
}
int main() {
    scanf("%d%d",&n,&q);
    for(int i=1;i<N;i++) mul[i]=1,val[i]=1,siz[i]=1;
    for(int i=1,u,v;i<n;i++) scanf("%d%d",&u,&v),link(u,v);
    char opt[10];int a,b,c,d;
    while(q--) {
        scanf("%s",opt);
        switch(opt[0]) {
            case '+':scanf("%d%d%d",&a,&b,&c);
                     makeroot(a);access(b);splay(b);
                     (add[b]+=c)%=mod;(val[b]+=c)%=mod;(sum[b]+=c*siz[b])%=mod;break;
            case '-':scanf("%d%d%d%d",&a,&b,&c,&d);cut(a,b),link(c,d);break;
            case '*':scanf("%d%d%d",&a,&b,&c);
                     makeroot(a),access(b);splay(b);
                     (mul[b]*=c)%=mod;(val[b]*=c)%=mod;(sum[b]*=c)%=mod;(add[b]*=c)%=mod;break;
            case '/':scanf("%d%d",&a,&b);
                     makeroot(a),access(b);splay(b);
                     printf("%lld
",sum[b]);break;
        }
    }
}
Tree II
我是咸鱼。转载博客请征得博主同意Orz
原文地址:https://www.cnblogs.com/sdfzhsz/p/9732692.html