题解 CF208E 【Blood Cousins】

Rusalka

2020-07-28 00:00:53

题解

原题链接:CF208E Blood Cousins

题意简述

思路与解答

Code

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>

using namespace std;

const int MAXN = 100010;

int n, m;

struct edge{
    int ne, to;
}e[MAXN];
int fir[MAXN], num = 0;
inline void join(int a, int b)
{
    e[++num].ne = fir[a];
    e[num].to = b;
    fir[a] = num;
}
int rt[MAXN], tot = 0;

int siz[MAXN], son[MAXN], f[MAXN][24], dep[MAXN], lg[MAXN];

void dfs1(int u)
{
    siz[u] = 1; dep[u] = dep[f[u][0]] + 1;
    for(int i=1;i<=lg[dep[u]];i++)
        f[u][i] = f[f[u][i-1]][i-1];
    for(int i=fir[u];i;i=e[i].ne)
    {
        int v = e[i].to;
        dfs1(v);
        siz[u] += siz[v];
        if(siz[son[u]] < siz[v]) son[u] = v;
    }
}
inline int kthparent(int u, int k)
{
    for(int i=lg[dep[u]];i>=0;i--)
        if(dep[u] - dep[f[u][i]] <= k) k -= dep[u] - dep[f[u][i]], u = f[u][i];
    return u;
}

struct qrys{
    int x, k, pa, ans;
}a[MAXN];
vector<int> vp[MAXN];

int cnt[MAXN], nowson = 0;
void calc(int u, int val)
{
    cnt[dep[u]] += val;
    for(int i=fir[u];i;i=e[i].ne)
    {
        int v = e[i].to;
        if(v == nowson) continue;
        calc(v, val);
    }
}

void dfs(int u, bool is)
{
    for(int i=fir[u];i;i=e[i].ne)
    {
        int v = e[i].to;
        if(v == son[u]) continue;
        dfs(v, 0);
    }
    if(son[u]) 
    {
        dfs(son[u], 1);
        nowson = son[u];
    }
    calc(u, 1);
    nowson = 0;
    for(int i=0;i<vp[u].size();i++)
        a[vp[u][i]].ans = cnt[dep[a[vp[u][i]].x]]-1;
    if(!is) calc(u, -1);
}

int main()
{
    scanf("%d",&n);
    lg[0] = -1;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&f[i][0]);
        if(f[i][0]) join(f[i][0], i);
        else rt[++tot] = i;
        lg[i] = lg[i>>1] + 1;
    }
    for(int i=1;i<=tot;i++)
        dfs1(rt[i]);
    scanf("%d",&m);
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&a[i].x,&a[i].k);
        a[i].pa = kthparent(a[i].x, a[i].k);
        vp[a[i].pa].push_back(i);
    }
    for(int i=1;i<=tot;i++)
        dfs(rt[i], 0);
    for(int i=1;i<=m;i++)
        printf("%d%c",a[i].ans," \n"[i==m]);
    return 0;
}