社区讨论

蒟蒻求助 dsu on tree TLE on 9#

CF246EBlood Cousins Return参与者 1已保存回复 0

讨论操作

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

当前回复
0 条
当前快照
1 份
快照标识符
@logkby1d
此快照首次捕获于
2023/11/02 10:23
2 年前
此快照最后确认于
2023/11/02 10:23
2 年前
查看原帖
C
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define PII pair<int, int>  
#define PSI pair<string, int>
const int MAX = 1e5 + 70;
string S[MAX];
int n, m, fa[MAX], top[MAX], id[MAX];
int bson[MAX], dep[MAX], siz[MAX];
int ANS[MAX];
int ID = 0;
map<string,int> hon;
vector<int> son[MAX];
vector<PII> ask[MAX]; 
vector<PII> hav[MAX];
int sum[MAX];  
int ans[MAX];
map<int, int> mp[MAX];
void pre_dfs(int x, int chain) { //划分轻重链 
	top[x] = chain;
	for(int to : son[x]) {
		if(to == bson[x] && bson[x] != n + 10) pre_dfs(to, chain);
		else pre_dfs(to, to); 
	}
}
void dfs_size(int x) { //求重儿子 
	if(x == 0) dep[x] = 0;
	else dep[x] = dep[fa[x]] + 1; 
	siz[x] = 1;
	int id = n + 10;
	for(int t : son[x]) {
		dfs_size(t);
		if(siz[t] > siz[id]) id = t;
	}
	bson[x] = id;
}
void dfs(int x) {
	for(auto y : son[x])  if(y != bson[x])  dfs(y);
	if(bson[x] != n + 10) dfs(bson[x]);
	if(bson[x] != n + 10) swap(hav[x], hav[bson[x]]); 
	for(auto y : son[x]) {
		if(y != bson[x]) { //  bson -> big_son 合并轻儿子 
			for(PII v : hav[y]) {
				int Nam = v.first;
				int Dep = v.second;
				if(mp[Dep][Nam] == 0) sum[Dep]++;
				mp[Dep][Nam]++;
				hav[x].push_back(v);
			}	
		}
		vector<PII> ttt; swap(ttt, hav[y]);
	}
	if(mp[dep[x]][id[x]] == 0) sum[dep[x]]++;
	mp[dep[x]][id[x]]++; PII Now; Now.first = id[x], Now.second = dep[x];
	hav[x].push_back(Now);
	for(PII y : ask[x]) {
		int op = y.first, Dep = y.second;
		ANS[op] = sum[Dep];
	}
	if(x == top[x]) {
		for(PII y : hav[x]) { //清空轻子树 
			mp[y.second][y.first]--;
			if(mp[y.second][y.first] == 0) sum[y.second]--;
		}
	}
}
int main() {
//	freopen("dsu.in","r",stdin);
	ios::sync_with_stdio(false);
	cin>>n;
	for(int i = 1; i <= n; i++) {
		int Fa;
		cin>>S[i];
		if(hon[S[i]]) id[i] = hon[S[i]];
		else {
			hon[S[i]] = ++ID;
			id[i] = hon[S[i]];	
//			printf("id[%d] %d\n", i ,id[i]);
		} 
		cin>>Fa;
		fa[i] = Fa;
		son[Fa].push_back(i);
	}
	dfs_size(0);
	pre_dfs(0, 0); 
	cin>>m;
	for(int i = 1; i <= m; i++) {
		int x, DEP; 
		cin>>x>>DEP;
		PII Now; Now.first = i, Now.second = (DEP + dep[x]);
		ask[x].push_back(Now);
	}
	dfs(0);
	for(int i = 1; i <= m; i++) {
		cout<<ANS[i]<<'\n';
	}
	return 0;
}

回复

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

正在加载回复...