luogu2590 [ZJOI2008]树的统计

Posted poorpool

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luogu2590 [ZJOI2008]树的统计相关的知识,希望对你有一定的参考价值。

树剖裸题

#include <iostream>
#include <cstdio>
using namespace std;
int n, uu, vv, hea[30005], ecnt, w[30005], ww[30005], dep[30005], cnt;
int idx[30005], son[30005], fa[30005], top[30005], q, wt[30005], siz[30005];
char ss[15];
struct Edge{
    int too, nxt;
}edge[60005];
void add_edge(int fro, int too){
    edge[++ecnt].nxt = hea[fro];
    edge[ecnt].too = too;
    hea[fro] = ecnt;
}
struct SGT{
    int sum[120005];
    int zdz[120005];
    void build(int o, int l, int r){
        if(l==r)    zdz[o] = sum[o] = wt[l];
        else{
            int mid=(l+r)>>1;
            int lson=o<<1;
            int rson=lson|1;
            zdz[lson] = zdz[rson] = -0x3f3f3f3f;
            if(l<=mid)  build(lson, l, mid);
            if(mid<r)   build(rson, mid+1, r);
            sum[o] = sum[lson] + sum[rson];
            zdz[o] = max(zdz[lson], zdz[rson]);
        }
    }
    void change(int o, int l, int r, int x, int k){
        if(l>=x && r<=x) sum[o] = zdz[o] = k;
        else{
            int mid=(l+r)>>1;
            int lson=o<<1;
            int rson=lson|1;
            if(x<=mid)  change(lson, l, mid, x, k);
            if(mid<x)   change(rson, mid+1, r, x, k);
            sum[o] = sum[lson] + sum[rson];
            zdz[o] = max(zdz[lson], zdz[rson]);
        }
    }
    int querySum(int o, int l, int r, int x, int y){
        if(l>=x && r<=y)    return sum[o];
        else{
            int mid=(l+r)>>1;
            int lson=o<<1;
            int rson=lson|1;
            int ans=0;
            if(x<=mid)  ans += querySum(lson, l, mid, x, y);
            if(mid<y)   ans += querySum(rson, mid+1, r, x, y);
            return ans;
        }
    }
    int queryZdz(int o, int l, int r, int x, int y){
        if(l>=x && r<=y)    return zdz[o];
        else{
            int mid=(l+r)>>1;
            int lson=o<<1;
            int rson=lson|1;
            int ans=-0x3f3f3f3f;
            if(x<=mid)  ans = max(ans, queryZdz(lson, l, mid, x, y));
            if(mid<y)   ans = max(ans, queryZdz(rson, mid+1, r, x, y));
            return ans;
        }
    }
}sgt;
void dfs1(int x, int f){
    fa[x] = f;
    dep[x] = dep[f] + 1;
    siz[x] = 1;
    int maxSon=-1;
    for(int i=hea[x]; i; i=edge[i].nxt){
        int t=edge[i].too;
        if(t==f)    continue;
        dfs1(t, x);
        siz[x] += siz[t];
        if(maxSon<siz[t]){
            maxSon = siz[t];
            son[x] = t;
        }
    }
}
void dfs2(int x, int topf){
    top[x] = topf;
    idx[x] = ++cnt;
    wt[cnt] = w[x];
    if(!son[x]) return ;
    dfs2(son[x], topf);
    for(int i=hea[x]; i; i=edge[i].nxt){
        int t=edge[i].too;
        if(t==fa[x] || t==son[x])   continue;
        dfs2(t, t);
    }
}
int queryRangeSum(int uu, int vv){
    int ans=0;
    while(top[uu]!=top[vv]){
        if(dep[top[uu]]<dep[top[vv]])   swap(uu, vv);
        ans += sgt.querySum(1, 1, n, idx[top[uu]], idx[uu]);
        uu = fa[top[uu]];
    }
    if(dep[uu]>dep[vv]) swap(uu, vv);
    ans += sgt.querySum(1, 1, n, idx[uu], idx[vv]);
    return ans;
}
int queryRangeZdz(int uu, int vv){
    int ans=-0x3f3f3f3f;
    while(top[uu]!=top[vv]){
        if(dep[top[uu]]<dep[top[vv]])   swap(uu, vv);
        ans = max(ans, sgt.queryZdz(1, 1, n, idx[top[uu]], idx[uu]));
        uu = fa[top[uu]];
    }
    if(dep[uu]>dep[vv]) swap(uu, vv);
    ans = max(ans, sgt.queryZdz(1, 1, n, idx[uu], idx[vv]));
    return ans;
}
int main(){
    cin>>n;
    for(int i=1; i<n; i++){
        scanf("%d %d", &uu, &vv);
        add_edge(uu, vv);
        add_edge(vv, uu);
    }
    for(int i=1; i<=n; i++)
        scanf("%d", &w[i]);
    dep[1] = 1;
    dfs1(1, 0);
    dfs2(1, 1);
    sgt.build(1, 1, n);
    cin>>q;
    while(q--){
        scanf("%s %d %d", ss, &uu, &vv);
        if(ss[1]==‘H‘)  sgt.change(1, 1, n, idx[uu], vv);
        if(ss[1]==‘M‘)  printf("%d\n", queryRangeZdz(uu, vv));
        if(ss[1]==‘S‘)  printf("%d\n", queryRangeSum(uu, vv));
    }
    return 0;
}

以上是关于luogu2590 [ZJOI2008]树的统计的主要内容,如果未能解决你的问题,请参考以下文章

luoguP2590 [ZJOI2008]树的统计(树链剖分)

P2590 [ZJOI2008]树的统计(树链剖分)

P2590 [ZJOI2008]树的统计

P2590 [ZJOI2008]树的统计

P2590 [ZJOI2008]树的统计

P2590 [ZJOI2008]树的统计(LCT)