LG 2590 树的统计

蒟蒻我一开始以为倍增搞搞即可
突然意识到修改……

emm,还是熟练剖分吧

#include <cstdio>
#include <cassert>

int read(){
    int x=0, f=1;char ch=getchar();
    while(ch<'0' || ch>'9'){if(ch=='-')f=-f;ch=getchar();}
    while(ch>='0' && ch<='9'){x=x*10+(ch-'0');ch=getchar();}
    return x*f;
}

const int MAXN=30111;
const int MAXM=200111;
const long long LONF=4567891012345678910LL;

long long max(long long a, long long b){
    return (a>b)?a:b;
}

int N, M;

struct Vert{
    int FE;
    int Dep, Size;
    int Fa, Son, Top;
    int Dps, Dpr;
    long long Val;
} V[MAXN];

struct Edge{
    int x, y, next;
} E[MAXN<<1];

int Ecnt=0;

void addE(int a, int b){
    ++Ecnt;
    E[Ecnt].x=a;E[Ecnt].y=b;E[Ecnt].next=V[a].FE;V[a].FE=Ecnt;
}

void DFS1(int at){
    V[at].Size=1;
    for(int k=V[at].FE, to;k>0;k=E[k].next){
        to=E[k].y;
        if(to==V[at].Fa)    continue;
        V[to].Fa=at;
        V[to].Dep=V[at].Dep+1;
        DFS1(to);
        V[at].Size+=V[to].Size;
        if(V[at].Son<=0 || V[to].Size>V[V[at].Son].Size)    V[at].Son=to;
    }
}

int Dfn[MAXN], DFN=0;

void DFS2(int at, int t){
    ++DFN;Dfn[DFN]=at;
    V[at].Dps=DFN;
    V[at].Top=t;
    if(V[at].Son>0) DFS2(V[at].Son, t);
    for(int k=V[at].FE, to;k>0;k=E[k].next){
        to=E[k].y;
        if(to==V[at].Fa || to==V[at].Son)   continue;
        DFS2(to, to);
    }
    V[at].Dpr=DFN;
}

struct Data{
    long long Sm, Mx;
    Data(long long _s=0LL, long long _m=-LONF){
        Sm=_s;Mx=_m;
    }
} ZERO;

Data operator + (Data a, Data b){
    return Data(a.Sm+b.Sm, max(a.Mx, b.Mx));
}

struct Node{
    int l, r;
    Data d;
} T[MAXN<<2];

int L, R;
long long op;

inline void pup(int &at){
    T[at].d=T[at<<1].d+T[(at<<1)|1].d;
}

void BuildTree(int l, int r, int at){
    T[at].l=l;T[at].r=r;
    int m=(l+r)>>1;
    if(l==r){
        T[at].d=Data(V[Dfn[m]].Val, V[Dfn[m]].Val);
        return;
    }
    BuildTree(l, m, at<<1);
    BuildTree(m+1, r, (at<<1)|1);
    pup(at);
}

inline void opr(int &at){
    T[at].d=Data(op, op);
}

void Update(int at){
    if(T[at].l>=L && T[at].r<=R){
        opr(at);
        return;
    }
    int m=(T[at].l+T[at].r)>>1;
    if(L<=m)    Update(at<<1);
    if(R>m) Update((at<<1)|1);
    pup(at);
}

Data Ask(int at){
    if(T[at].l>=L && T[at].r<=R){
        return T[at].d;
    }
    int m=(T[at].l+T[at].r)>>1;
    Data ret=ZERO;
    if(L<=m)    ret=ret+Ask(at<<1);
    if(R>m) ret=ret+Ask((at<<1)|1);
    return ret;
}

Data Ask_index(int a, int b){
    Data ret=ZERO;
    while(V[a].Top!=V[b].Top){
        if(V[V[a].Top].Dep>V[V[b].Top].Dep){
            L=V[V[a].Top].Dps;R=V[a].Dps;
            ret=ret+Ask(1);
            a=V[V[a].Top].Fa;
        }
        else{
            L=V[V[b].Top].Dps;R=V[b].Dps;
            ret=ret+Ask(1);
            b=V[V[b].Top].Fa;
        }
    }
    if(V[a].Dep>V[b].Dep){
        L=V[b].Dps;R=V[a].Dps;
        ret=ret+Ask(1);
    }
    else{
        L=V[a].Dps;R=V[b].Dps;
        ret=ret+Ask(1);
    }
    return ret;
}

int main(){
    
    N=read();
    for(int i=1, a, b;i<N;++i){
        a=read();b=read();
        addE(a, b);addE(b, a);
    }
    for(int i=1;i<=N;++i)   V[i].Val=read();
    
    V[1].Dep=1;
    DFS1(1);
    DFS2(1, 1);
    
    assert(DFN==N);
    BuildTree(1, N, 1);
    
    M=read();
    char com[111];
    Data ANS;
    for(int i=1, a, b, c;i<=M;++i){
        scanf("%s", com);
        if(com[0]=='C'){
            a=read();c=read();
            L=V[a].Dps;R=V[a].Dps;op=c;
            Update(1);
        }
        else{
            a=read();b=read();
            ANS=Ask_index(a, b);
            if(com[1]=='M'){
                printf("%lld\n", ANS.Mx);
            }
            if(com[1]=='S'){
                printf("%lld\n", ANS.Sm);
            }
        }
    }
    
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Pickupwin/p/9099298.html
今日推荐