树剖模板by fcdalao

#include<bits/stdc++.h>
using namespace std;
const int MX=30011;
struct Edge{int to,nxt;}e[2*MX];
struct node{int mx;long long sum;}t[4*MX];
int n,Index,fir[MX],fa[MX],dfn[MX],dep[MX],siz[MX],son[MX],Top[MX],w[MX],bel[MX],dfs_cnt;
inline void ins(int u,int v){e[++Index]=(Edge){v,fir[u]},fir[u]=Index;}
void dfs1(int x){
    siz[x]++,dep[x]=dep[fa[x]]+1;
    for(int i=fir[x];i;i=e[i].nxt)if(e[i].to!=fa[x]){
        fa[e[i].to]=x;
        dfs1(e[i].to);
        siz[x]+=siz[e[i].to];
        if(siz[e[i].to]>siz[son[x]])son[x]=e[i].to;
    }
}
void dfs2(int x){
    Top[x]=(son[fa[x]]==x)?Top[fa[x]]:x;
    dfn[x]=++dfs_cnt,bel[dfs_cnt]=x;
    if(!son[x])return;
    dfs2(son[x]);
    for(int i=fir[x];i;i=e[i].nxt)if(e[i].to!=fa[x]&&e[i].to!=son[x]){
        dfs2(e[i].to);
    }
}
#define ls(x) (x<<1)
#define rs(x) (x<<1|1)
inline void push_up(int o){
    t[o].mx=max(t[ls(o)].mx,t[rs(o)].mx);
    t[o].sum=t[ls(o)].sum+t[rs(o)].sum;
}
void build(int L,int R,int o){
    if(L==R){t[o].sum=t[o].mx=w[bel[L]];return;}
    int mid=L+R>>1;
    build(L,mid,ls(o)),build(mid+1,R,rs(o));
    push_up(o);
}
void updata(int L,int R,int o,int x,int v){
    if(L==R){t[o].mx=t[o].sum=v;return;}
    int mid=L+R>>1;
    if(x<=mid)updata(L,mid,ls(o),x,v);
    else updata(mid+1,R,rs(o),x,v);
    push_up(o);
}
long long query(int L,int R,int o,int l,int r,int f){
    if(L==l&&R==r)return (~f)?t[o].sum:t[o].mx;
    int mid=L+R>>1;
    if(r<=mid)return query(L,mid,ls(o),l,r,f);
    else if(l>mid) return query(mid+1,R,rs(o),l,r,f);
    else {
        if(~f)return query(L,mid,ls(o),l,mid,f)+query(mid+1,R,rs(o),mid+1,r,f);
        else return max(query(L,mid,ls(o),l,mid,f),query(mid+1,R,rs(o),mid+1,r,f));
    }
}
const int inf=0x7fffffff;
long long Query(int u,int v,int f){
    long long ret=(~f)?0:-inf;
    while(Top[u]!=Top[v]){
        if(dep[Top[u]]<dep[Top[v]])swap(u,v);
        if(~f)ret+=query(1,n,1,dfn[Top[u]],dfn[u],f);
        else ret=max(ret,query(1,n,1,dfn[Top[u]],dfn[u],f));
        u = fa[Top[u]];
    }
    if(dep[u]<dep[v])swap(u,v);
    if(~f)ret+=query(1,n,1,dfn[v],dfn[u],f);
    else ret=max(ret,query(1,n,1,dfn[v],dfn[u],f));
    return ret;
}
char op[20];
int main(){
    #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
    #endif
    scanf("%d",&n);
    for(int i=1;i<n;i++){
        int u,v;scanf("%d%d",&u,&v);
        ins(u,v),ins(v,u);
    }
    for(int i=1;i<=n;i++)scanf("%d",w+i);
    dfs1(1),dfs2(1),build(1,n,1);
    int q,u,v;scanf("%d",&q);
    while(q--){
        scanf("%s%d%d",op,&u,&v);
        if(*op=='C')updata(1,n,1,dfn[u],v);
        else printf("%lld
",op[1]=='S'?Query(u,v,1):Query(u,v,-1));
    }
} 
View Code
原文地址:https://www.cnblogs.com/Amphetamine/p/7191787.html