链接:
题意: 现在有一些树,树的节点有一个颜色(用字符串给出) 和他的父亲,父亲如果是0 表明是根节点,然后m次查询,每次查询一个u 和k 问你在u这棵子树上,与u 相距为k的点的颜色个数。
思路:首先应该是用dsu on tree 来解决这个问题, 如果我们把当前询问的u节点当做标准的话,那么在向上回溯的时候肯定是不好转移的,所以直接以根节点作为标准,set 统计颜色个数。然后就是对于节点u,k 我查询深度为k+dep【u】 的set就可以了。有个坑点就是dep[ u ]+k 可能会越界 。
代码:
#include<bits/stdc++.h>using namespace std;
const int N =1e5+5;set<int >se[N];
multiset<int >mse[N];
int col[N];
struct node
{int k;int id;int ans;
};
vector< int >ve[N];
vector< node >qu[N];
int n,m;
map<string ,int >mp;
int tot;
int dep[N];
int sz[N];
bool big[N];
node xun[N];bool cmp1(node a,node b)
{return a.id<b.id;
}void dfs1(int u,int deep)
{dep[u]=deep;sz[u]=1;for(int i=0;i<ve[u].size();i++){int v=ve[u][i];dfs1(v,deep+1);sz[u]+=sz[v];}
}void add(int u,int flag)
{int deep=dep[u];if(flag==1){se[deep].insert(col[u]);mse[deep].insert(col[u]);}else{mse[deep].erase(col[u]);if(mse[deep].find(col[u])==mse[deep].end()){se[deep].erase(col[u]);}}for(int i=0;i<ve[u].size();i++){int v=ve[u][i];if(big[v]) continue;add(v,flag);}
}void dfs(int u,int keep)
{int mx=-1,bigc=-1;for(int i=0;i<ve[u].size();i++){int v=ve[u][i];if(sz[v]>mx){mx=sz[v];bigc=v;}}for(int i=0;i<ve[u].size();i++){int v=ve[u][i];if(v!=bigc){dfs(v,0);}}if(bigc!=-1){dfs(bigc,1);big[bigc]=1;}add(u,1);// tongjifor(int i=0;i<qu[u].size();i++){int k=qu[u][i].k;if(dep[u]+k>1e5) continue;qu[u][i].ans=se[dep[u]+k].size();}if(bigc!=-1){big[bigc]=0;}if(keep==0){add(u,-1);}
}int rt[N];
int rttot;int main()
{scanf("%d",&n);int fa; string s;int r;for(int i=1;i<=n;i++){cin>>s>>fa;if(fa==0){rt[++rttot]=i;}if(mp[s]==0){ve[fa].push_back(i);col[i]=++tot;mp[s]=tot;}else{ve[fa].push_back(i);col[i]=mp[s];}}int u,k;scanf("%d",&m);for(int i=1;i<=m;i++){scanf("%d %d",&u,&k);qu[u].push_back((node){k,i,0});}for(int i=1;i<=rttot;i++){r=rt[i];dfs1(r,0);dfs(r,0);}tot=0;for(int i=1;i<=n;i++){for(int j=0;j<qu[i].size();j++){xun[++tot]=qu[i][j];}}sort(xun+1,xun+tot+1,cmp1);for(int i=1;i<=tot;i++){printf("%dn",xun[i].ans);}return 0;
}
本文发布于:2024-01-31 09:28:39,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170666452027533.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |