[USACO12DEC]逃跑的BarnRunning Away From…

题意

给出以1号点为根的一棵有根树,问每个点的子树中与它距离小于等于l的点有多少个

题解

似乎有好多种做法啊……然而蒟蒻只会打打主席树的板子……

调了一个上午一直WA……狠下心来重打一遍居然直接一遍过……

先dfs一遍,把到根节点的距离算出来,然后建出树上的主席树

然后考虑,$d[v]-d[u]<=L$,$d[v]<=L+d[u]$

然后就是对于每一个$d[u]+L$查询一下区间内有多少比它小的就好

细节问题:因为不能保证$d[u]+L$在离散化后的数组内存在,所以要用upper_bound,并查询比它小的,而且要在离散化的数组后面加一个inf

 1 //minamoto
 2 #include<bits/stdc++.h>
 3 #define N 200005
 4 #define M 4000005
 5 #define ll long long
 6 #define inf 0x3f3f3f3f
 7 using namespace std;
 8 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
 9 char buf[1<<21],*p1=buf,*p2=buf;
10 inline ll read(){
11     #define num ch-'0'
12     char ch;bool flag=0;ll res;
13     while(!isdigit(ch=getc()))
14     (ch=='-')&&(flag=true);
15     for(res=num;isdigit(ch=getc());res=res*10+num);
16     (flag)&&(res=-res);
17     #undef num
18     return res;
19 }
20 char obuf[1<<24],*o=obuf;
21 void print(int x){
22     if(x>9) print(x/10);
23     *o++=x%10+48;
24 }
25 int sum[M],L[M],R[M],rt[N];
26 int ver[N<<1],Next[N<<1],head[N];ll edge[N<<1];
27 int ls[N],rs[N];ll a[N],b[N];
28 int n,m,cnt,tot;ll p;
29 void update(int last,int &now,int l,int r,int x){
30     sum[now=++cnt]=sum[last]+1;
31     if(l==r) return;
32     int mid=(l+r)>>1;
33     if(x<=mid) R[now]=R[last],update(L[last],L[now],l,mid,x);
34     else L[now]=L[last],update(R[last],R[now],mid+1,r,x);
35 }
36 int query(int u,int v,int l,int r,int k){
37     if(r<k) return sum[v]-sum[u];
38     if(l>=k) return 0;
39     int mid=(l+r)>>1;
40     if(k<=mid) return query(L[u],L[v],l,mid,k);
41     else return query(R[u],R[v],mid+1,r,k)+sum[L[v]]-sum[L[u]];
42 }
43 inline void add(int u,int v,ll e){
44     ver[++tot]=v,Next[tot]=head[u],head[u]=tot,edge[tot]=e;
45 }
46 void dfs(int u,int fa,ll d){
47     b[ls[u]=++m]=d,a[m]=d;
48     for(int i=head[u];i;i=Next[i])
49     if(ver[i]!=fa) dfs(ver[i],u,d+edge[i]);
50     rs[u]=m;
51 }
52 int main(){
53     n=read(),p=read();
54     for(int u=2;u<=n;++u){
55         int v=read();ll e=read();
56         add(v,u,e);
57     }
58     dfs(1,0,0);
59     sort(b+1,b+1+m);
60     m=unique(b+1,b+1+m)-b-1;
61     for(int i=1;i<=n;++i){
62         int k=lower_bound(b+1,b+1+m,a[i])-b;
63         update(rt[i-1],rt[i],1,m,k);
64     }
65     b[m+1]=inf;
66     for(int i=1;i<=n;++i){
67         int k=upper_bound(b+1,b+2+m,a[ls[i]]+p)-b;
68         k=query(rt[ls[i]-1],rt[rs[i]],1,m,k);
69         print(k);
70         *o++='\n';
71     }
72     fwrite(obuf,o-obuf,1,stdout);
73     return 0;
74 }

 

posted @ 2018-07-31 12:10  bztMinamoto  阅读(275)  评论(0编辑  收藏  举报
Live2D