[ZJOI2008]树的统计

这就是个树剖板子。。。板子。。。板子。。。

维护一个sum,一个max,就好了。。。QAQ。。。

然而我数组开小。。。调了一天。。。艹

呆码:

#include<iostream>
#include<cstdio>
#define INF 99999999
#define maxn 100060
#define ll long long
using namespace std;

ll sum[maxn];
int num,head[maxn],siz[maxn],dep[maxn];
int id[maxn],cnt,wt[maxn],w[maxn],fa[maxn],n;
int top[maxn],son[maxn],big[maxn];
char ch[11];

struct asd{
    int nxt;
    int to;
} a[maxn];

inline void add(int x,int y)
{
    a[++num].nxt=head[x];
    a[num].to=y;
    head[x]=num;
}

inline void dfs1(int x,int father,int deep)
{
    dep[x]=deep; fa[x]=father; siz[x]=1;
    int maxson=-1;
    for(int i=head[x];i;i=a[i].nxt)
    {
        int to=a[i].to; if(to==father) continue;
        dfs1(to,x,deep+1); siz[x]+=siz[to];
        if(siz[to]>maxson)
        {
            son[x]=to;
            maxson=siz[to];
        }
    }
}

inline void dfs2(int x,int topp)
{
    id[x]=++cnt; wt[cnt]=w[x]; top[x]=topp;
    if(!son[x]) return;
    dfs2(son[x],topp);
    for(int i=head[x];i;i=a[i].nxt)
    {
        if(a[i].to==fa[x] || a[i].to==son[x])
            continue;
        dfs2(a[i].to,a[i].to);
    }
}

inline void pushup(int rt)
{
    sum[rt]=sum[rt<<1]+sum[rt<<1|1];
    big[rt]=max(big[rt<<1],big[rt<<1|1]);
}

inline void build(int rt,int l,int r)
{
    if(l==r)
    {
        sum[rt]=wt[l];
        big[rt]=wt[l];
        return;
    }
    int mid=l+r>>1;
    build(rt<<1,l,mid);
    build(rt<<1|1,mid+1,r);
    pushup(rt);
}

inline void update(int rt,int l,int r,int L,int k)
{
    int mid=l+r>>1;
    if(l==r) { sum[rt]=k; big[rt]=k; return;}
    if(L<=mid) update(rt<<1,l,mid,L,k);
    else update(rt<<1|1,mid+1,r,L,k);
    pushup(rt);
}

inline int queryx(int rt,int l,int r,int L,int R)
{
    if(L<=l && r<=R)
    {
        return big[rt];
    }
    int ans=-INF;
    int mid=l+r>>1;
    if(L<=mid) ans=max(ans,queryx(rt<<1,l,mid,L,R));
    if(R>mid) ans=max(ans,queryx(rt<<1|1,mid+1,r,L,R));
    pushup(rt);
    return ans;
}

inline int queryX(int x,int y)
{
    int ans=-INF;
    while(top[x]!=top[y])
    {
        if(dep[top[x]]<dep[top[y]]) swap(x,y);
        ans=max(ans,queryx(1,1,n,id[top[x]],id[x]));
        x=fa[top[x]];
    }
    if(dep[x]>dep[y]) swap(x,y);
    ans=max(ans,queryx(1,1,n,id[x],id[y]));
    return ans;
}

inline ll querys(int rt,int l,int r,int L,int R)
{
    if(L<=l && r<=R)
    {
        return sum[rt];
    }
    int mid=l+r>>1;
    ll ans=0;
    if(L<=mid) ans+=querys(rt<<1,l,mid,L,R);
    if(R>mid) ans+=querys(rt<<1|1,mid+1,r,L,R);
    pushup(rt);
    return ans;
}

inline ll queryS(int x,int y)
{
    ll ans=0;
    while(top[x]!=top[y])
    {
        if(dep[top[x]]<dep[top[y]]) swap(x,y);
        ans+=querys(1,1,n,id[top[x]],id[x]);
        x=fa[top[x]];
    }
    if(dep[x]>dep[y]) swap(x,y);
    ans+=querys(1,1,n,id[x],id[y]);
    return ans;
}

int main()
{
    scanf("%d",&n);
    int x,y;
    for(int i=1;i<=n-1;i++)
    {
        scanf("%d%d",&x,&y);
        add(x,y); add(y,x);
    }
    for(int i=1;i<=n;i++)
        scanf("%d",&w[i]);
    dfs1(1,0,1); dfs2(1,1);
    build(1,1,n);
    int Q,u,v;
    scanf("%d",&Q);
    while(Q--)
    {
        scanf("%s%d%d",ch,&u,&v);
        if(ch[3]=='N') update(1,1,n,id[u],v);
        if(ch[3]=='X') printf("%d
",queryX(u,v));
        if(ch[3]=='M') printf("%lld
",queryS(u,v));
    }
}
代码
原文地址:https://www.cnblogs.com/zzzyc/p/9213105.html