【玄关】dsu on tree板子求调
  • 板块学术版
  • 楼主mysterys
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/9/12 17:02
  • 上次更新2024/9/12 17:13:07
查看原帖
【玄关】dsu on tree板子求调
659165
mysterys楼主2024/9/12 17:02

RTRT,求得是子树内最小的众数,O(nlog2n)O(n log^2 n) 做法样例过不去。

#include<bits/stdc++.h>
using namespace std;
#define FILE(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout);
#define ll long long
#define endl '\n'
const int N=5e5+5;
int n,q;
struct edge{
	int nxt,to;
}e[N];
int head[N],cnt,col[N];
map<int,int>mp[N];
int ans[N],nxt[N];
inline void add(int u,int v){
	e[++cnt]=(edge){head[u],v};
	head[u]=cnt;
}
inline void dfs(int u,int fa){
	int res=2e9,maxx=0;
	mp[u][col[u]]++;nxt[u]=u;
	if(maxx<mp[u][col[u]]){
		maxx=mp[u][col[u]];res=col[u];
	}
	else if(mp[u][col[u]]==maxx) res=min(res,col[u]);
	for(int i=head[u];i;i=e[i].nxt){
		int v=e[i].to;
		if(v==fa) continue;
		dfs(v,u);
		if(mp[nxt[u]].size()<mp[nxt[v]].size()) {
			int tmp=nxt[u];nxt[u]=nxt[v];nxt[v]=tmp;
		}
		for(auto l:mp[nxt[v]]){
			mp[nxt[u]][l.first]+=l.second;
			if(maxx<mp[nxt[u]][l.first]) {
				maxx=mp[nxt[u]][l.first];res=l.first;
			}else if(maxx==mp[nxt[u]][l.first]){
				res=min(res,l.first);
			}
		}
	}
	ans[u]=(res==2e9?1:res);
}
signed main(){
	FILE("violet2");
	cin.tie(nullptr)->sync_with_stdio(false);
	cout.tie(nullptr);
	cin>>n;
	for(int i=1;i<=n;i++) cin>>col[i];
	for(int i=1;i<n;i++){
		int u,v;cin>>u>>v;
		add(u,v);add(v,u);
	}
	dfs(1,0);
	cin>>q;
	while(q--){
		int x;cin>>x;
		cout<<ans[x]<<endl;
	}
	return 0;
}
2024/9/12 17:02
加载中...