社区讨论

样例过了 0pts求调

P2590[ZJOI2008] 树的统计参与者 1已保存回复 0

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
0 条
当前快照
1 份
快照标识符
@mimx6aof
此快照首次捕获于
2025/12/01 17:01
3 个月前
此快照最后确认于
2025/12/01 21:16
3 个月前
查看原帖
CPP
#include<bits/stdc++.h>
#define ls 1<<o
#define rs (1<<o)+1
const int N=6e4+10;
using namespace std;
int wc[N],sz[N],f[N],rdn[N],dep[N],cnt,top[N],n,sum;
struct node{
	int val,maxn;
}tree[4*N];
vector<int> a[N];
void update(int o,int l,int r,int x,int res){
	if(l==r){
		tree[o].val=tree[o].maxn=res;
		return ;
	}
	int mid=l+r>>1;
	if(x<=mid) update(ls,l,mid,x,res);
	else update(rs,mid+1,r,x,res);
	tree[o].val=tree[ls].val+tree[rs].val;
	tree[o].maxn=max(tree[ls].maxn,tree[rs].maxn);
	return ;
}
int query(int o,int l,int r,int left,int right,int op){
	if(l>=left&&r<=right){
		if(op==2) return tree[o].val;
		if(op==1) return tree[o].maxn;
	}
	int mid=l+r>>1;
	int val=0,sum=-0x3f3f3f3f;
	if(left<=mid){
        if(op==1)sum=max(sum,query(ls,l,mid,left,right,1));
		if(op==2)val+=query(ls,l,mid,left,right,2);
	}
	if(right>mid){
		if(op==1) sum=max(sum,query(rs,mid+1,r,left,right,1));
		if(op==2) val+=query(rs,mid+1,r,left,right,2);
	}
	if(op==1) return sum;
	else return val;
}
void dfs1(int x,int fa){
	dep[x]=dep[fa]+1;
	f[x]=fa;
	sz[x]=1;
	for(int i=0;i<a[x].size();i++){
		if(a[x][i]==fa) continue;
		dfs1(a[x][i],x);
		if(sz[a[x][i]]>sz[wc[x]])
			wc[x]=a[x][i];
		sz[x]+=sz[a[x][i]];
	}
	return ;
}
void dfs2(int x,int Top){
	top[x]=Top;
	rdn[x]=++cnt;
	if(wc[x]) dfs2(wc[x],Top);
	for(int i=0;i<a[x].size();i++){
		if(a[x][i]==wc[x]||a[x][i]==f[x]) continue;
		dfs2(a[x][i],a[x][i]);
	}
}
int solve(int a,int b,int op){
	int sum=-0x3f3f3f3f,val=0;
	while(top[a]!=top[b]){
		if(dep[top[a]]<dep[top[b]]) swap(a,b);
		if(op==1) sum=max(sum,query(1,1,n,rdn[top[a]],rdn[a],1));
		if(op==2) val+=query(1,1,n,rdn[top[a]],rdn[a],2);
		a=f[top[a]];
	}
	if(rdn[b]<rdn[a]) swap(a,b);
	if(op==1) sum=max(sum,query(1,1,n,rdn[a],rdn[b],1));
	if(op==2) val+=query(1,1,n,rdn[a],rdn[b],2);
	return op==1?sum:val;
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
    for(int i=1;i<=100000;i++) tree[i].val=0,tree[i].maxn=-0x3f3f3f3f;
	cin>>n;
	for(int i=1;i<=n-1;i++){
		int u,v;
		cin>>u>>v;
		a[u].push_back(v);
		a[v].push_back(u);
	}
	dfs1(1,0);
	dfs2(1,1);
	for(int i=1;i<=n;i++){
		int u;
		cin>>u;
		update(1,1,n,rdn[i],u);
	}
	int T;
	cin>>T;
	while(T--){
		string str;
		cin>>str;
		if(str=="CHANGE"){
			int u,t;
			cin>>u>>t;
			update(1,1,n,rdn[u],t);
		}
		if(str=="QMAX"){
			int a,b;
			cin>>a>>b;
			cout<<solve(a,b,1)<<"\n";
		}
		if(str=="QSUM"){
			int a,b;
			cin>>a>>b;
			if(rdn[a]>rdn[b]) swap(a,b);
			cout<<solve(a,b,2)<<"\n";
		}
	}
	return 0;
}

回复

0 条回复,欢迎继续交流。

正在加载回复...