luoguP3066 [USACO12DEC]逃跑的BarnRunning

luoguP3066 [USACO12DEC]逃跑的BarnRunning

题目大意

给定一棵n个节点的树和参数L,查询每个节点子树中到达该节点距离<=L的数量(包括该节点)

偏模板的主席树

PS:注意一下输入格式

dfs:得出每个子树时间戳区间,每个节点到根节点的距离,仔细理解一下几个数组的含义吧,dalao直接略过

update:这题以时间戳(i)为关键字继承(i-1)

query:直接查询每个子树的时间戳区间里<=dep[i]+L

这里用到了一个小技巧,就是为了避免特判,b数组加一个虚节点inf,查询<now的就好了

My complete code:

#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long LL;
const LL maxn=3e5;
const LL inf=1e18;
inline LL read(){
	LL x=0,f=1; char c=getchar();
	while(c<'0'||c>'9'){
		if(c=='-') f=-1; c=getchar();
	}
	while(c>='0'&&c<='9'){
		x=x*10+c-'0'; c=getchar();
	}return x*f;
}
struct node{
	LL to,next,d;
}dis[maxn];
LL n,L,num,nod,num1,cnt; 
LL head[maxn],dep[maxn],b[maxn],low[maxn],dfn[maxn],sot[maxn],date[maxn<<7],lt[maxn<<7],rt[maxn<<7],root[maxn];
inline void add(LL u,LL v,LL d){
	dis[++num]=(node){v,head[u],d}; head[u]=num;
}
void dfs(LL u,LL fa){
	sot[++num1]=u;
	b[++cnt]=dep[u];
	dfn[u]=++num;
	for(LL i=head[u];i;i=dis[i].next){
		LL v=dis[i].to;
		dep[v]=dep[u]+dis[i].d;
		dfs(v,u);
	}
	low[u]=num;
}
void update(LL &now,LL pre,LL l,LL r,LL c){
	now=++nod;
	date[now]=date[pre]+1;
	if(l==r)
	    return;
	LL mid=(l+r)>>1;
	if(c<=mid){
		update(lt[now],lt[pre],l,mid,c);
		rt[now]=rt[pre];
	}else{
		update(rt[now],rt[pre],mid+1,r,c);
		lt[now]=lt[pre];
	}
}
LL query(LL pre,LL next,LL l,LL r,LL c){//<c
	LL mid=(l+r)>>1;
	if(r<c)
	    return date[next]-date[pre];
	LL ans=0;
	if(l<c)
		ans+=query(lt[pre],lt[next],l,mid,c);
	if(mid+1<c)
		ans+=query(rt[pre],rt[next],mid+1,r,c);
	return ans;
}
int main(){
	scanf("%lld%lld",&n,&L);
	for(LL v=2;v<=n;++v){
		LL u=read(),e=read();
		add(u,v,e);
	}
	num=0;
	dfs(1,0);
	sort(b+1,b+1+cnt);
	b[++cnt]=inf;
	cnt=unique(b+1,b+1+cnt)-b-1;
	for(LL i=1;i<=n;++i){
		LL u=sot[i];
		LL now=lower_bound(b+1,b+1+cnt,dep[u])-b;
		update(root[i],root[i-1],1,cnt,now);
	}
	for(LL i=1;i<=n;++i){
		LL l=dfn[i],r=low[i];
		LL now=upper_bound(b+1,b+1+cnt,dep[i]+L)-b;
		printf("%lld\n",query(root[l-1],root[r],1,cnt,now));
	}
	return 0;
}/*
4 5 
1 4 
2 3 
1 5 

3
2
1
1
*/

  

posted @ 2018-12-06 10:05  y2823774827y  阅读(146)  评论(0编辑  收藏  举报