其实也差不多是dsu的模板题了
#include <bits/stdc++.h>
using namespace std;
const int maxn=3e5+10;
struct edge{
int u,to,nxt,ans;
}d[maxn],ask[maxn]; int head[maxn],cnt=1,head1[maxn],cnt1=1;
void add(int u,int v){
d[++cnt]=(edge){u,v,head[u],0},head[u]=cnt;
}
void ins(int u,int v){
ask[++cnt1]=(edge){u,v,head1[u],0},head1[u]=cnt1;
}
map<string,int>mp;
int id,son[maxn],siz[maxn],deep[maxn],has[maxn];
string a[maxn];
void dfs(int u,int father,int depth)
{
siz[u]=1,deep[u]=depth;
int maxson=-1;
for(int i=head[u];i;i=d[i].nxt )
{
int v=d[i].to;
if( v==father ) continue;
dfs(v,u,depth+1);
siz[u]+=siz[v];
if( maxson<siz[v] ) maxson=siz[v],son[u]=v;
}
}
int nowson;
set<int>s[maxn];
void update(int u,int father,int val)
{
if( val==1 ) s[deep[u]].insert(has[u]);
else s[ deep[u] ].erase( has[u] );
for(int i=head[u];i;i=d[i].nxt )
{
if( d[i].to!=father&&d[i].to!=nowson )
update(d[i].to,u,val);
}
}
void dsu(int u,int father,bool keep)
{
for(int i=head[u];i;i=d[i].nxt )
{
int v=d[i].to;
if( v==father || v==son[u] ) continue;
dsu(v,u,0);
}
if( son[u] ) dsu(son[u],u,1),nowson=son[u];
update(u,father,1); nowson=0;
for(int i=head1[u];i;i=ask[i].nxt )
{
int v=ask[i].u;
ask[i].ans=s[deep[u]+ask[i].to].size();
}
/*处理答案
*/
if( !keep ) update(u,father,-1);
}
int main()
{
int root=0;
int n,m;
cin >> n;
for(int i=1;i<=n;i++)
{
int x; cin >> a[i] >> x;
if( !mp[a[i]] ) mp[a[i]]=++id;
has[i]=mp[a[i]];
if( x==0 ) add(root,i),add(i,root);
else add(i,x),add(x,i);
}
dfs(root,0,1);
cin >> m;
for(int i=1;i<=m;i++)
{
int l,r; cin >> l >> r;
ins(l,r);
}
dsu(root,0,1);
for(int i=2;i<=m+1;i++)
cout << ask[i].ans << '\n';
}