离线逆序并查集20分求助,悬赏关注
查看原帖
离线逆序并查集20分求助,悬赏关注
546681
lcbridgeAK CSP-S楼主2023/7/10 11:19
#include <bits/stdc++.h>
using namespace std;
const int MAXN=100005;
int n,q,fa[MAXN],x[MAXN],y[MAXN],e[MAXN],sz[MAXN],cnt,ans[MAXN],a[MAXN],opr[MAXN];
bool vis[MAXN]; 
vector <int> g[MAXN];
int find(int x){
	if(x==fa[x])return x;
	return fa[x]=find(fa[x]);
}
int main(){
	scanf("%d%d",&n,&q);
	for(int i=1;i<=n;i++)scanf("%d",&a[i]);
	for(int i=1;i<n;i++)scanf("%d%d",&x[i],&y[i]);
	for(int i=1;i<=q;i++){
		int val;
		scanf("%d%d",&opr[i],&e[i]);
		if(opr[i]==1)vis[e[i]]=1;
		else if(opr[i]==2){
			scanf("%d",&val);
			g[e[i]].push_back(a[e[i]]);
			a[e[i]]=val;
		} 
	} 
	for(int i=1;i<n;i++){
		if(!vis[i]){
			int u=x[i];
			int v=y[i];
			int fu=find(u);
			int fv=find(v);
			if(fu!=fv){
				fa[fu]=fv;
				sz[fv]+=sz[fu];
				sz[fu]=0;
			}
		}
	}	
	for(int i=1;i<=n;i++){
		fa[i]=i;
		sz[i]=a[i];
	}
	for(int i=q;i>=1;i--){
		if(opr[i]==1){
			int u=x[e[i]];
			int v=y[e[i]];
			int fu=find(u);
			int fv=find(v);
			if(fu!=fv){
				fa[fu]=fv;
				sz[fv]+=sz[fu];
				sz[fu]=0;
			}
		}
		else if(opr[i]==2){
			int v=g[e[i]][g[e[i]].size()-1];
			g[e[i]].pop_back();
			sz[find(e[i])]+=v-a[e[i]];
			a[e[i]]=v;
		}
		else ans[++cnt]=sz[find(e[i])];
	}
	for(int i=cnt;i>=1;i--)printf("%d\n",ans[i]);
	return 0;
}
2023/7/10 11:19
加载中...