P5384 [Cnoi2019] 雪松果树

P5384 [Cnoi2019] 雪松果树

题目背景

幻想乡,冬。

一年一度,生长在高山上的雪松果树又结果了。

Cirno 不知从哪弄到了 \(1,2,3\cdots9\) 颗雪松果,然后很开心的吃掉了其中 \(6\) 颗,最后还剩最后 \(1\) 颗。

Cirn o因为以后吃不到雪松果而感到忧愁,于是决定种在美丽的雾之湖畔。

第一天,发芽。

第二天,雪松果树长成了一颗参天大树, 上面长满了雪松果。

Cirno 在雪松果成熟之前早有一些问题想知道,但现在她忙于收集雪松果,就把问题丢给了你。

题目描述

雪松果树是一个以 \(1\) 为根有着 \(N\) 个节点的树。

除此之外, Cirno还有 \(Q\) 个询问,每个询问是一个二元组 \((u,k)\) ,表示询问 \(u\) 节点的 \(k\)-cousin 有多少个。

我们定义:

节点 \(u\)\(1\)-father 为 路径 \((1, u)\) (不含 u)上距 u 最近的节点

节点 \(u\)\(k\)-father 为 节点 「\(u\)\((k-1)\)-father」 的 1-father

节点 \(u\)\(k\)-son 为所有 \(k\)-father 为 \(u\) 的节点

节点 \(u\)\(k\)-cousin 为 节点「 \(u\)\(k\)-father」的 \(k\)-son (不包含 \(u\) 本身)

数据范围:

对于 100% 的数据 \(N,Q \le 10^6\)

Solution:

说句闲话:

感谢 red_fire 大神的推荐。

看题面时:水题。
口胡时:水题。
然而爆唐的我本人总能把自己口胡的思路实现得爆炸就是了。

言归正传:

我们要实现的东西其实很简单,就是对于一个点 \(x\) 求出他的树上 \(k\) 级祖先,然后查询他的 \(k\) 级祖先子树下深度与 \(x\) 相等的节点个数,然后再把 \(x\) 扣掉就好了。

实现:

我们可以维护一个桶 \(bac_i\) 表示深度为 \(i\) 的节点当前有多少个。由于我们只统计当前子树内的,所以我们要做一个差分,在访问到当前节点 \(x\) 且未访问其后代时先减去桶中原有的值,在访问完该节点的后代之后再加上桶中的值,就得到了该子树下对应的桶中的值。

所以我们要将询问离线并挂到 \(x\)\(k\) 级祖先上,在 dfs 时直接查询。

Code:

#include<bits/stdc++.h>
const int lg=20;
const int N=1e6+6;
using namespace std;
int n,m,cnt;
int dep[N],bac[N],f[N][lg+1],bit[lg+5],ans[N];
vector<int> E[N];
vector<tuple<int,int> > Q[N];
void dfs(int x,int fa)
{
    dep[x]=dep[fa]+1;
    for(auto [k,id] : Q[x]){ans[id]-=bac[dep[x]+k];}
    for(int y : E[x])dfs(y,x);bac[dep[x]]++;
    for(auto [k,id] : Q[x]){ans[id]+=bac[dep[x]+k];}
}
inline int k_fa(int x,int k){ for(int i=lg;i>=0;i--)if(k>=bit[i])k-=bit[i],x=f[x][i];return x;}
void work()
{
    cin>>n>>m;bit[0]=1;for(int i=1;i<=lg;i++)bit[i]=bit[i-1]<<1;
    for(int u=2;u<=n;u++){scanf("%d",&f[u][0]);E[f[u][0]].emplace_back(u);}
    for(int x=1;x<=n;x++)for(int j=1;j<=lg;j++)f[x][j]=f[f[x][j-1]][j-1];
    for(int i=1,x,k;i<=m;i++)
    {
        scanf("%d%d",&x,&k);
        int y=k_fa(x,k);ans[i]=-1;
        if(!y||k==0){ans[i]=0;continue;}
        Q[y].emplace_back(k,i);
    }
    dfs(1,0);
    for(int i=1;i<=m;i++)printf("%d ",ans[i]);
}
int main()
{
    work();return 0;
}
posted @ 2025-02-19 14:17  liuboom  阅读(14)  评论(0)    收藏  举报