题解 P5384 [Cnoi2019] 雪松果树
这题有紫??
对于询问节点 ,倍增地跳到它的 级祖先,求其子树内有多少深度为 的节点。
我们考虑把询问离线,再通过 dfs 序把树拍平,然后扫一遍直接求就行了。
复杂度 。
code:
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
inline int read(){
int x=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
while (ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
return x*f;
}
int n,q,ans[N],l[N],r[N],tot=0,a[N],dep[N],fa[N][22],cnt[N];
vector<int>adj[N];
struct node{
int val,id,op;
node(int val=0,int id=0,int op=0):val(val),id(id),op(op){}
};
vector<node>d[N];
void dfs(int u,int lst){
l[u]=++tot;dep[u]=dep[lst]+1;a[tot]=dep[u];
for(int i=1;i<=20;++i)fa[u][i]=fa[fa[u][i-1]][i-1];
for(int i=0;i<adj[u].size();++i)dfs(adj[u][i],u);
r[u]=tot;
}
int main(){
cin>>n>>q;
for(int i=2;i<=n;++i){
fa[i][0]=read();
adj[fa[i][0]].push_back(i);
}
dfs(1,0);
for(int i=1;i<=q;++i){
int u,t,v;u=read();t=read();v=dep[u];
for(int i=0;i<=20;++i)if((t>>i)&1)u=fa[u][i];
d[l[u]-1].push_back(node(v,i,-1));
d[r[u]].push_back(node(v,i,1));
}
for(int i=1;i<=n;++i){
++cnt[a[i]];
for(int j=0;j<d[i].size();++j){
node tmp=d[i][j];
ans[tmp.id]+=tmp.op*cnt[tmp.val];
}
}
for(int i=1;i<=q;++i)printf("%d ",max(ans[i]-1,0));
cout<<endl;
return 0;
}
本文作者:HQJ2007
本文链接:https://www.cnblogs.com/HQJ2007/p/17561374.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!