题意
给出以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++=' '; 71 } 72 fwrite(obuf,o-obuf,1,stdout); 73 return 0; 74 }