bzoj 1036: [ZJOI2008]树的统计Count

Posted lxy8584099

tags:

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

宏定义害死人

 

/**************************************************************
    Problem: 1036
    User: lxy8584099
    Language: C++
    Result: Accepted
    Time:3008 ms
    Memory:6648 kb
****************************************************************/
 
// luogu-judger-enable-o2
/*
    树的统计
    树剖模板
    线段树维护区间 
    max min 再也不敢用宏定义了 。。。 
*/
#pragma GCC optimize(3)//手动Ox优化+
#include<cstdio> 
#define il inline
#define inf (0x3fffffff)
#define mid ((l+r)>>1) 
#define int long long
using namespace std;
const int N=30050;
struct pp {int v,nxt;} e[N<<1]; 
int n,m,a[N],head[N],tot;
int id[N],mxs[N],size[N],dep[N],top[N],fa[N];
int mx[N<<2],sum[N<<2],w[N];
inline int max(int x,int y){
    return x>y?x:y;
}
il void Init()
{
    scanf("%lld",&n);
    for(int i=1,u,v;i<n;i++)
    {
        scanf("%lld%lld",&u,&v);
        e[++tot].nxt=head[u];head[u]=tot;e[tot].v=v;
        e[++tot].nxt=head[v];head[v]=tot;e[tot].v=u;
    }
    for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
}
il void Dfs1(int u)
{
    size[u]=1;dep[u]=dep[fa[u]]+1;
    int maxn=-1;
    for(int j=head[u];j;j=e[j].nxt)
    {
        int v=e[j].v;if(v==fa[u]) continue;
        fa[v]=u;Dfs1(v);size[u]+=size[v];
        if(maxn<size[v]) maxn=size[v],mxs[u]=v;
    }
}
il void Dfs2(int u,int tp)
{
    id[u]=++tot;top[u]=tp;w[id[u]]=a[u];
    if(!mxs[u]) return ;
    Dfs2(mxs[u],tp);
    for(int j=head[u];j;j=e[j].nxt)
    {
        int v=e[j].v;
        if(v==fa[u]||v==mxs[u]) continue;
        Dfs2(v,v);
    }
}
il void push_up(int rt) 
{
    sum[rt]=sum[rt<<1]+sum[rt<<1|1];
    mx[rt]=max(mx[rt<<1],mx[rt<<1|1]);
}
il void Build(int rt,int l,int r)
{
    if(l>=r) {sum[rt]=mx[rt]=w[l];return ;} 
    Build(rt<<1,l,mid);Build(rt<<1|1,mid+1,r);
    push_up(rt);
}
il void Change(int rt,int l,int r,int k,int val)
{
    if(l>=r) {sum[rt]=mx[rt]=val;return ;} 
    if(k<=mid) Change(rt<<1,l,mid,k,val);
    else Change(rt<<1|1,mid+1,r,k,val);
    push_up(rt);
}
il int Tree_max(int rt,int l,int r,int L,int R)
{
    if(L<=l&&r<=R) return mx[rt];
    int res=-inf;
    if(L<=mid) res=max(res,Tree_max(rt<<1,l,mid,L,R));
    if(R>mid) res=max(res,Tree_max(rt<<1|1,mid+1,r,L,R));
    return res;
}
il int List_max(int x,int y)
{
    int res=-inf;
    while(top[x]!=top[y])
    {
        if(dep[top[x]]<dep[top[y]]) x^=y^=x^=y;
        int r=id[x],l=id[top[x]];x=fa[top[x]];
        res=max(res,Tree_max(1,1,n,l,r));
    }
    int l=id[x],r=id[y]; if(l>r) l^=r^=l^=r;
    res=max(res,Tree_max(1,1,n,l,r)); return res;
}
il int Tree_sum(int rt,int l,int r,int L,int R)
{
    if(L<=l&&r<=R) return sum[rt];
    int res=0;
    if(L<=mid) res+=Tree_sum(rt<<1,l,mid,L,R);
    if(R>mid) res+=Tree_sum(rt<<1|1,mid+1,r,L,R);
    return res;
}
il int List_sum(int x,int y)
{
    int res=0;
    while(top[x]!=top[y])
    {
        if(dep[top[x]]<dep[top[y]]) x^=y^=x^=y;
        int r=id[x],l=id[top[x]];x=fa[top[x]];
        res+=Tree_sum(1,1,n,l,r);
    }
    int l=id[x],r=id[y]; if(l>r) l^=r^=l^=r;
    res+=Tree_sum(1,1,n,l,r); return res;
}
il void Solve()
{
    Dfs1(1);tot=0;Dfs2(1,1);Build(1,1,n);
    scanf("%lld",&m); while(m--)
    {
        char S[10];int u,v;
        scanf("%s%lld%lld",S,&u,&v);
        if(S[0]==C) Change(1,1,n,id[u],v);
        else if(S[1]==M) printf("%lld
",List_max(u,v));
        else printf("%lld
",List_sum(u,v));
    }
}
signed main()
{
    Init();
    Solve();
    return 0;
}

 

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

bzoj 1036: [ZJOI2008]树的统计Count

bzoj 1036: [ZJOI2008]树的统计Count

BZOJ 1036: [ZJOI2008]树的统计Count [树链剖分]

bzoj 1036 [ZJOI2008]树的统计Count(树链剖分,线段树)

[Bzoj1036][ZJOI2008]树的统计Count

bzoj 1036 [ZJOI2008]树的统计Count 树链剖分模板