Codeforces 246E Blood Cousins Return

来源:互联网 发布:安卓去软件广告 编辑:程序博客网 时间:2024/06/06 06:47

Codeforces 246E Blood Cousins Return

数据结构,dsu on tree

题意

一棵树,每一个点有一个颜色(字符串),每一次询问以某一个点为根的子树中与其距离为k的点有多少种颜色。

思路

dsu on tree。因为第二次dfs时每个深度的信息都要记录,就对每一个深度开一个set,记录这个深度下出现过的颜色即可。
dfs完一个节点,将它的深度加上询问的深度,就是实际深度,查询这个深度的set的size即可。
注意不是树,是森林,记一下所有的root即可。

代码

#include<bits\stdc++.h>#define M(a,b) memset(a,b,sizeof(a))#define lson l,mid,rt<<1#define rson mid+1,r,rt<<1|1using namespace std;const int MAXN=100007;typedef long long LL;struct Edge{    int to, ne;}e[MAXN<<1];int head[MAXN], edgenum;int val[MAXN];struct Query{    int k, ne;int id;}qn[MAXN];int qhead[MAXN], qam;int sz[MAXN], hson[MAXN], dp[MAXN];map<string, int> ha;void findson(int u, int fa){    sz[u]=1;    if(fa==-1) dp[u]=1;    else dp[u]=dp[fa]+1;    for(int i=head[u];~i;i=e[i].ne)    {        int to=e[i].to;        if(to!=fa)        {            findson(to, u);            if(!hson) hson[u]=to;            else if(sz[hson[u]]<sz[to]) hson[u]=to;            sz[u]+=sz[to];        }    }}int hs;set<int> cnt[MAXN];void suan(int u, int fa, int v){    if(v==1)        cnt[dp[u]].insert(val[u]);    else cnt[dp[u]].erase(val[u]);    for(int i=head[u];~i;i=e[i].ne)        if(e[i].to!=fa&&e[i].to!=hs)            suan(e[i].to, u, v);}int res[MAXN];void dfs(int u, int fa, int kp){    for(int i=head[u];~i;i=e[i].ne)    {        int to=e[i].to;        if(to!=fa&&to!=hson[u])            dfs(to, u, 0);    }    if(hson[u]) dfs(hson[u], u, 1), hs=hson[u];    suan(u, fa, 1);hs=0;    for(int i=qhead[u];~i;i=qn[i].ne)    {        int hi=dp[u]+qn[i].k;        if(hi>=MAXN) res[qn[i].id]=0;        else res[qn[i].id]=cnt[hi].size();    }    if(!kp) suan(u, fa, -1);}vector<int> roots;int main(){    int n;    while(scanf("%d", &n)==1)    {        M(head, -1), M(qhead, -1);edgenum=qam=0;        roots.clear();        int colam=0;        for(int i=1;i<=n;i++)        {            string tmps;cin>>tmps;            if(!ha[tmps]) ha[tmps]=++colam, val[i]=colam;            else val[i]=ha[tmps];            int p=i, q;scanf("%d", &q);            if(q==0)            {                roots.push_back(i);                continue;            }            e[edgenum].to=q, e[edgenum].ne=head[p], head[p]=edgenum++;            e[edgenum].to=p, e[edgenum].ne=head[q], head[q]=edgenum++;        }        int q;scanf("%d", &q);        for(int i=1;i<=q;i++)        {            int t1, t2;scanf("%d%d", &t1, &t2);            qn[qam].k=t2, qn[qam].ne=qhead[t1], qn[qam].id=i, qhead[t1]=qam++;        }        for(int i : roots)            findson(i, -1);        for(int i:roots)            dfs(i, -1, 0);        for(int i=1;i<=q;i++)            printf("%d\n", res[i]);    }    //system("pause");    return 0;}
原创粉丝点击