社区讨论
蒟蒻求助 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 条回复,欢迎继续交流。
正在加载回复...