树剖模板题求调
查看原帖
树剖模板题求调
373198
WhileTrueRP楼主2024/8/7 17:14

AC on #5 #6 #9。

#include<bits/stdc++.h>
using namespace std;
const int N = 3e4+5;
const int INF = 1e9+7;
int n,q;
int a[N];
int f[N],sz[N],hs[N],dep[N];
int dfn[N],top[N],tot = 0;
vector<int> e[N];
string opt;
struct node{
	int sum,maxn;
}tree[N<<2];
void dfs1(int u,int fa){
	dep[u] = dep[fa] + 1;
	sz[u] = 1;
	f[u] = fa;
	for(auto v:e[u]){
		if(v == fa){
			continue;
		}
		dfs1(v,u);
		sz[u] += sz[v];
		if(sz[v] > sz[hs[u]]){
			hs[u] = v;
		}
	}
}
void dfs2(int u,int t){
	dfn[u] = ++tot;
	top[u] = t;
	if(!hs[u]){
		return;
	}
	dfs2(hs[u],t);
	for(auto v:e[u]){
		if(v == f[u] || v == hs[u]){
			continue;
		}
		dfs2(v,v);
	}
}
void update(int p){
	tree[p].maxn = max(tree[p<<1].maxn,tree[p<<1|1].maxn);
	tree[p].sum = tree[p<<1].sum + tree[p<<1|1].sum;
}
void build(int p,int l,int r){
	if(l == r){
		tree[p].maxn = tree[p].sum = a[dfn[l]];
		return;
	}
	int mid = (l+r) >> 1;
	build(p<<1,l,mid);
	build(p<<1|1,mid+1,r);
	update(p);
}
void change(int p,int l,int r,int x,int c){
	if(l == r){
		tree[p].maxn = c;
		tree[p].sum = c;
		return;
	}
	int mid = (l+r) >> 1;
	if(x <= mid){
		change(p<<1,l,mid,x,c);
	}else{
		change(p<<1|1,mid+1,r,x,c);
	}
	update(p);
}
int query_max(int p,int l,int r,int ll,int rr){
	if(l == ll && r == rr){
		return tree[p].maxn;
	}
	int mid = (l+r) >> 1;
	if(rr <= mid){
		return query_max(p<<1,l,mid,ll,rr);
	}else if(ll > mid){
		return query_max(p<<1|1,mid+1,r,ll,rr);
	}else{
		return max(query_max(p<<1,l,mid,ll,mid),query_max(p<<1|1,mid+1,r,mid+1,rr));
	}
}
int query_sum(int p,int l,int r,int ll,int rr){
	if(l == ll && r == rr){
		return tree[p].sum;
	}
	int mid = (l+r) >> 1;
	if(rr <= mid){
		return query_sum(p<<1,l,mid,ll,rr);
	}else if(ll > mid){
		return query_sum(p<<1|1,mid+1,r,ll,rr);
	}else{
		return query_sum(p<<1,l,mid,ll,mid) + query_sum(p<<1|1,mid+1,r,mid+1,rr);
	}
}
int main(){
	for(int i=0;i<(N<<2);i++){
		tree[i].maxn = -INF;
	}
	scanf("%d",&n);
	for(int i=1;i<=n-1;i++){
		int x,y;
		scanf("%d%d",&x,&y);
		e[x].push_back(y);
		e[y].push_back(x);
	}
	dfs1(1,0);
	dfs2(1,1);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
	}
	build(1,1,n);
	scanf("%d",&q);
	for(int i=1;i<=q;i++){
		int x,y;
		cin>>opt;
		scanf("%d%d",&x,&y);
		if(opt == "CHANGE"){
			change(1,1,n,dfn[x],y);
		}else if(opt == "QMAX"){
			int res = -INF;
			while(top[x] != top[y]){
				if(dep[top[x]] < dep[top[y]]){
					swap(x,y);
				}
				res = max(res,query_max(1,1,n,dfn[top[x]],dfn[x]));
				x = f[top[x]];
			}
			if(dfn[x] > dfn[y]){
				swap(x,y);
			}
			res = max(res,query_max(1,1,n,dfn[x],dfn[y]));
			printf("%d\n",res);
		}else{
			int res = 0;
			while(top[x] != top[y]){
				if(dep[top[x]] < dep[top[y]]){
					swap(x,y);
				}
				res += query_sum(1,1,n,dfn[top[x]],dfn[x]);
				x = f[top[x]];
			}
			if(dfn[x] > dfn[y]){
				swap(x,y);
			}
			res += query_sum(1,1,n,dfn[x],dfn[y]);
			printf("%d\n",res);
		}
	}
}
2024/8/7 17:14
加载中...