刚学树剖,30分求助
查看原帖
刚学树剖,30分求助
200044
JS_TZ_ZHR楼主2020/5/15 09:39

RT

#include<bits/stdc++.h>
using namespace std;
int n,m,root=1,u,v,a[300005];
int dep[300005],son[300005],size[300005],f[300005];
int p[300005],sum[300005],top[300005],cnt;
vector<int>ve[300005];
struct Segment_Tree {
	int s,Max;
} tree[300005<<2|1];
void dfs1(int now,int fa,int deep) {
	dep[now]=deep;
	f[now]=fa;
	size[now]=1;
	int maxsize=-1;
	for(int i=0; i<ve[now].size(); i++) {
		int y=ve[now][i];
		if(y==fa)continue;
		dfs1(y,now,deep+1);
		size[now]+=size[y];
		if(size[y]>maxsize)maxsize=size[y],son[now]=y;
	}
	return;
}
void dfs2(int now,int _top) {
	p[now]=++cnt;
	top[now]=_top;
	sum[cnt]=a[now];
	if(!son[now])return;
	dfs2(son[now],_top);
	for(int i=0; i<ve[now].size(); i++) {
		int y=ve[now][i];
		if(y==f[now]||y==son[now])continue;
		dfs2(y,y);
	}
	return;
}
inline void push_up(int p) {
	int ls=p<<1,rs=p<<1|1;
	tree[p].s=tree[ls].s+tree[rs].s;
	tree[p].Max=max(tree[ls].Max,tree[rs].Max);
	return;
}
void change(int now,int l,int r,int p,int k) {
	if(l==r&&r==now) {
		tree[p].s=tree[p].Max=k;
		return;
	}
	int mid=(l+r)>>1;
	if(mid>=now)change(now,l,mid,p<<1,k);
	else change(now,mid+1,r,p<<1|1,k);
	push_up(p);
	return;
}
int query1(int l1,int r1,int l,int r,int p) {
	if(l>=l1&&r<=r1)return tree[p].s;
	int mid=(l+r)>>1,ans=0;
	if(mid>=l1)ans+=query1(l1,r1,l,mid,p<<1);
	if(mid<r1)ans+=query1(l1,r1,mid+1,r,p<<1|1);
	return ans;
}
int query2(int l1,int r1,int l,int r,int p) {
	if(l>=l1&&r<=r1)return tree[p].Max;
	int mid=(l+r)>>1,ans=-1e9;
	if(mid>=l1)ans=max(ans,query2(l1,r1,l,mid,p<<1));
	if(mid<r1)ans=max(ans,query2(l1,r1,mid+1,r,p<<1|1));
	return ans;
}
int _query1(int x,int y){
	int ans=0;
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]])swap(x,y);
		ans+=query1(p[top[x]],p[x],1,n,1);
		x=f[top[x]];
	}
	if(dep[x]>dep[y])swap(x,y);
	ans+=query1(p[x],p[y],1,n,1);
	return ans;
}
int _query2(int x,int y){
	int ans=-1e9;
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]])swap(x,y);
		ans=max(ans,query2(p[top[x]],p[x],1,n,1));
		x=f[top[x]];
	}
	if(dep[x]>dep[y])swap(x,y);
	ans=max(ans,query2(p[x],p[y],1,n,1));
	return ans;
}
void build(int l,int r,int p) {
	if(l==r) {
		tree[p].s=tree[p].Max=sum[l];
		return;
	}
	int mid=(l+r)>>1;
	build(l,mid,p<<1);
	build(mid+1,r,p<<1|1);
	push_up(p);
}
int main() {
	scanf("%d",&n);
	for(int i=1; i<n; i++) {
		scanf("%d%d",&u,&v);
		ve[u].push_back(v);
		ve[v].push_back(u);
	}
	for(int i=1; i<=n; i++)scanf("%d",&a[i]);
	dfs1(root,0,1);
	dfs2(root,root);
	build(1,n,1);
	scanf("%d",&m);
	string opt;
	while(m--) {
		cin>>opt>>u>>v;
		if(opt=="CHANGE")change(u,1,n,1,v);
		if(opt=="QSUM")printf("%d\n",_query1(u,v));
		if(opt=="QMAX")printf("%d\n",_query2(u,v));
	}
}
2020/5/15 09:39
加载中...