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 [树链剖分]