社区讨论

求条玄关,马峰优良pwp

P3313[SDOI2014] 旅行参与者 1已保存回复 0

讨论操作

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

当前回复
0 条
当前快照
1 份
快照标识符
@mk6lr44j
此快照首次捕获于
2026/01/09 16:16
上个月
此快照最后确认于
2026/01/09 16:18
上个月
查看原帖
C
#include<bits/stdc++.h>
#define int long long
#define lowbit(x) (x&-x)
#define ull unsigned long long
#define int128 __int128
#define faster ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define mid ((l+r)>>1)
using namespace std;
const int maxn=1e5+10;
int tot;
int n,q;
int root[maxn];
namespace segment_trees{
	struct node{
		int ls,rs,sumseg,maxseg;
	}nd[maxn*50];
	int newp;
	struct segment_tree{
		void pushup(int k){
			nd[k].sumseg=nd[k].maxseg=0;
			if(nd[k].ls)nd[k].sumseg+=nd[nd[k].ls].sumseg,nd[k].maxseg=max(nd[k].maxseg,nd[nd[k].ls].maxseg);
			if(nd[k].rs)nd[k].sumseg+=nd[nd[k].rs].sumseg,nd[k].maxseg=max(nd[k].maxseg,nd[nd[k].rs].maxseg);
		}
		void change(int &k,int l,int r,int x,int y){
			if(l>x||r<x)return;
			if(!k)k=++newp;
			if(l==r){
				nd[k].sumseg=nd[k].maxseg=y;
				return;
			}
			change(nd[k].ls,l,mid,x,y);
			change(nd[k].rs,mid+1,r,x,y);
			pushup(k);
		}
		int querysum(int k,int l,int r,int x,int y){
			if(!k||l>y||r<x)return 0;
			if(l>=x&&r<=y)return nd[k].sumseg;
			return querysum(nd[k].ls,l,mid,x,y)+querysum(nd[k].rs,mid+1,r,x,y);
		}
		int querymax(int k,int l,int r,int x,int y){
			if(!k||l>y||r<x)return 0;
			if(l>=x&&r<=y)return nd[k].maxseg;
			return max(querymax(nd[k].ls,l,mid,x,y),querymax(nd[k].rs,mid+1,r,x,y));
		}
	}tr[maxn];
};
using namespace segment_trees;
vector<int>g[maxn];
int dep[maxn],sz[maxn],fa[maxn];
int dfn[maxn],top[maxn],son[maxn],dfc;
void dfs1(int u,int from){
	fa[u]=from;
	sz[u]=1,son[u]=-1;
	dep[u]=dep[from]+1;
	for(int v:g[u]){
		if(v==from)continue;
		dfs1(v,u);
		sz[u]+=sz[v];
		if(son[u]==-1||sz[v]>sz[son[u]])son[u]=v;
	}
	return;
}
void dfs2(int u,int tp){
	dfn[u]=++dfc;
	top[u]=tp;
	if(son[u]==-1)return;
	dfs2(son[u],tp);
	for(int v:g[u])
	if(v!=son[u]&&v!=fa[u])
	dfs2(v,v);
	return;
}
int w[maxn],col[maxn];
int qsum(int u,int v,int cc){
	int ret=0;
	while(top[u]!=top[v]){
		if(dep[top[u]]<dep[top[v]])swap(u,v);
		ret+=tr[cc].querysum(root[cc],1,n,dfn[top[u]],dfn[u]);
		u=fa[top[u]];
	}
	if(dep[u]>dep[v])swap(u,v);
	ret+=tr[cc].querysum(root[cc],1,n,dfn[u],dfn[v]);
	return ret;
}
int qmax(int u,int v,int cc){
	int ret=0;
	while(top[u]!=top[v]){
		if(dep[top[u]]<dep[top[v]])swap(u,v);
		ret=max(ret,tr[cc].querymax(root[cc],1,n,dfn[top[u]],dfn[u]));
		u=fa[top[u]];
	}
	if(dep[u]>dep[v])swap(u,v);
	ret=max(ret,tr[cc].querymax(root[cc],1,n,dfn[u],dfn[v]));
	return ret;
}
void solve(){
	cin>>n>>q;
	for(int i=1;i<=n;i++)cin>>w[i]>>col[i];
	for(int i=1;i<n;i++){
		int u,v;
		cin>>u>>v;
		g[u].push_back(v);
		g[v].push_back(u);
	} 
	dfs1(1,1);
	dfs2(1,1);
	for(int i=1;i<=n;i++)tr[col[i]].change(root[col[i]],1,n,dfn[i],w[i]);
	while(q--){
		string opt;
		cin>>opt;
		if(opt=="CC"){
			int x,y;
			cin>>x>>y;
			tr[col[x]].change(root[col[x]],1,n,dfn[x],-w[x]);
			col[x]=y;
			tr[col[x]].change(root[col[x]],1,n,dfn[x],w[x]);
		}
		else if(opt=="CW"){
			int x,y;
			cin>>x>>y;
			tr[col[x]].change(root[col[x]],1,n,dfn[x],-w[x]);
			w[x]=y;
			tr[col[x]].change(root[col[x]],1,n,dfn[x],w[x]);
		}
		else if(opt=="QS"){
			int u,v;
			cin>>u>>v;
			cout<<qsum(u,v,col[u])<<'\n';
		}
		else{
			int u,v;
			cin>>u>>v;
			cout<<qmax(u,v,col[u])<<'\n';
		}
	}
}
signed main(){
	faster;
	int T=1;
	while(T--)solve();
}

回复

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

正在加载回复...