码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj 1036: [ZJOI2008]树的统计Count

时间:2018-12-29 13:44:16      阅读:188      评论:0      收藏:0      [点我收藏+]

标签:using   std   col   memory   zjoi2008   res   scan   problem   enable   

宏定义害死人

 

/**************************************************************
    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\n",List_max(u,v));
        else printf("%lld\n",List_sum(u,v));
    }
}
signed main()
{
    Init();
    Solve();
    return 0;
}

 

bzoj 1036: [ZJOI2008]树的统计Count

标签:using   std   col   memory   zjoi2008   res   scan   problem   enable   

原文地址:https://www.cnblogs.com/lxy8584099/p/10195119.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!