hybz1036 树的统计Count

#include#include#includeusing namespace std;const int Max=30009;inline int MAX(int a,int b){return a>b?a:b;}int val[Max];struct SemgentTree{int sum[Max<<2],maxv[Max<<2];inline void PushUp(int idx){maxv[idx]=MAX(maxv[idx<<1],maxv[idx<<1|1]);sum[idx]=sum[idx<<1]+sum[idx<<1 1="" void="" build="" int="" idx="" int="" left="" int="" right="" if="" left="=right)" maxv="" idx="" sum="" idx="" val="" left="" return="" int="" mid="(left+right)">>1;Build(idx<<1,left,mid);Build(idx<<1 1="" mid="" 1="" right="" pushup="" idx="" void="" update="" int="" idx="" int="" left="" int="" right="" int="" pos="" int="" data="" if="" left="=right)" maxv="" idx="" sum="" idx="" data="" return="" int="" mid="(left+right)">>1;if(pos<=mid) Update(idx<<1,left,mid,pos,data);else Update(idx<<1|1,mid+1,right,pos,data);PushUp(idx);}int QueryMax(int idx,int left,int right,int L,int R){if(L<=left && right<=R)return maxv[idx];int mid=(left+right)>>1,ans=-Max;if(L<=mid) ans=MAX(ans,QueryMax(idx<<1,left,mid,L,R));if(mid<R) ans=MAX(ans,QueryMax(idx<<1|1,mid+1,right,L,R));return ans;}int QuerySum(int idx,int left,int right,int L,int R){if(L<=left && right<=R)return sum[idx];int mid=(left+right)>>1,ans=0;if(L<=mid) ans+=QuerySum(idx<<1,left,mid,L,R);if(mid<R) ans+=QuerySum(idx<<1|1,mid+1,right,L,R);return ans;}}tree;struct Edge{int v,next;}edge[Max<<1 int="" f="" max="" fa="" max="" tot="" max="" son="" max="" depth="" max="" top="" max="" pos="" max="" weight="" max="" size="" void="" init="" fa="" 1="" top="" 1="" 1="" depth="" 1="" size="0;" void="" dfs1="" int="" cur="" tot="" cur="" 1="" son="" cur="" 0="" int="" v="" maxv="-1;" for="" int="" i="f[cur];i!=-1;i=edge[i].next)" v="edge[i].v;" if="" v="" fa="" cur="" fa="" v="" cur="" depth="" v="" depth="" cur="" 1="" dfs1="" v="" tot="" cur="" tot="" v="" if="" tot="" v="">maxv) maxv=tot[v],son[cur]=v;}}}void Dfs2(int cur){pos[cur]=++size;val[size]=weight[cur];int v=son[cur],i;if(v) top[v]=top[cur],Dfs2(v);for(i=f[cur];i!=-1;i=edge[i].next){v=edge[i].v;if(v!=fa[cur] && v!=son[cur]) top[v]=v,Dfs2(v);}}void Add(int u,int v,int& cnt){edge[cnt].v=v;edge[cnt].next=f[u];f[u]=cnt++;edge[cnt].v=u;edge[cnt].next=f[v];f[v]=cnt++;}int Query(int u,int v,bool type)//true为求和{// if(u==v) return weight[u];int topu=top[u],topv=top[v];int ans=type?0:-Max;while(topu != topv){if(depth[topu]depth[v]) swap(u,v);if(type) ans+=tree.QuerySum(1,1,size,pos[u],pos[v]);else ans=MAX(ans,tree.QueryMax(1,1,size,pos[u],pos[v]));return ans;}int main(){//freopen("test.txt","r",stdin);int N,M,u,v,i,cnt;char str[19];while(~scanf("%d",&N)){memset(f,-1,sizeof(f));for(i=1,cnt=0;i<N;++i){scanf("%d %d",&u,&v);Add(u,v,cnt);}for(i=1;i<=N;++i)scanf("%d",weight+i);Init();Dfs1(1),Dfs2(1);tree.Build(1,1,N);scanf("%d",&M);while(M--){scanf("%s%d%d",str,&u,&v);if(str[1]=='H') tree.Update(1,1,N,pos[u],v);else printf("%d\n",Query(u,v,str[1]=='S'));}}return 0;}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值