Codeforces 246E Blood Cousins Return

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|1
using 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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章