ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

luogu P5384 [Cnoi2019]雪松果树

2021-06-19 22:02:37  阅读:200  来源: 互联网

标签:tmp int luogu Cnoi2019 yyy dfs P5384 include define


题面传送门
显然线段树合并\(O(nlogn)\)可惜被卡了。
我们考虑另外一种写法。
首先对于每个点要求\(k\)级祖先。因为没有强制在线所以不用长链剖分,直接树上dfs一边然后开栈存储即可。
再将每个询问挂在\(k\)级祖先上再dfs一遍,这一次对于每个询问,减掉遍历子树前的答案,加上遍历子树后的答案就是子树内的答案。
注意没有\(k\)级祖先输出\(0\)。这样时间复杂度就是\(O(n)\)了。
code:

#include <vector>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<cmath>
#include<algorithm>
#include<bitset>
#include<set>
#include<map>
#define I inline
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define abs(x) ((x)>0?(x):-(x))
#define re register
#define ll long long
#define db double
#define N 1000000
#define M 50
#define W (1<<20)
#define mod 1000000007
#define eps (1e-7)
#define U unsigned int
#define IT set<ques>::iterator
using namespace std;
int n,m,k,x,y,z,st[N+5],sh,ans[N+5],f[N+5],d[N+5],A[N+5],B[N+5];
struct ques{int num,x;}now;vector<ques>Q[N+5];
struct yyy{int to,z;};
struct ljb{
	int head,h[N+5];yyy f[N+5];
	inline void add(int x,int y){f[++head]=(yyy){y,h[x]};h[x]=head;}
}s;
I void dfs(int x,int last){
	st[++sh]=x;yyy tmp;d[x]=d[last]+1;
	for(int i=0;i<Q[x].size();i++)now=Q[x][i],A[now.num]=(sh-now.x>0?st[sh-now.x]:0);
	for(int i=s.h[x];i;i=tmp.z)tmp=s.f[i],dfs(tmp.to,x);sh--;
}
I void Make(int x){
	for(int i=0;i<Q[x].size();i++)now=Q[x][i],ans[now.num]-=f[now.x]+1; 
	f[d[x]]++;yyy tmp;for(int i=s.h[x];i;i=tmp.z)tmp=s.f[i],Make(tmp.to);
	for(int i=0;i<Q[x].size();i++) now=Q[x][i],ans[now.num]+=f[now.x];
}
static char buf[10000000],*p1=buf,*p2=buf;
#define getchar() p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++
I void read(int &x){
	char s=getchar();x=0;
	while(s<'0'||s>'9') s=getchar();
	while(s>='0'&&s<='9') x=x*10+s-48,s=getchar();
}
I void print(int x){if(x>9) print(x/10);putchar(x%10+48);}
int main(){
	freopen("1.in","r",stdin);
	re int i,j;scanf("%d%d",&n,&m);for(i=2;i<=n;i++) read(x),s.add(x,i);
	for(i=1;i<=m;i++) read(A[i]),read(B[i]),Q[A[i]].push_back((ques){i,B[i]});dfs(1,0);for(i=1;i<=n;i++) Q[i].clear();
	for(i=1;i<=m;i++) A[i]&&(Q[A[i]].push_back((ques){i,B[i]+d[A[i]]}),0);
    Make(1);/*for(i=1;i<=n;i++) f[i]+=f[i-1];*/for(i=1;i<=n;i++) (!A[i])&&(ans[i]=0);
    for(i=1;i<=m;i++) printf("%d ",ans[i]); 	
}

标签:tmp,int,luogu,Cnoi2019,yyy,dfs,P5384,include,define
来源: https://www.cnblogs.com/275307894a/p/14905071.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有