比较巧妙地统计路径长度。直接用g[i][j-1],g[f[i][j-1]][j-1]去计算当前路径的长度。
然后就像找lca一样每次往上跳,不过不是二进制分解是统计长度。
1 #include<cstdio> 2 #define it register int 3 #define il inline 4 const int N=1000005; 5 int f[N][20],g[N][20],n,s,ans; 6 il void fr(int &num){ 7 num=0;char c=getchar();int p=1; 8 while(c<'0'||c>'9') c=='-'?p=-1,c=getchar():c=getchar(); 9 while(c>='0'&&c<='9') num=num*10+c-'0',c=getchar(); 10 num*=p; 11 } 12 int main(){ 13 fr(n),fr(s); 14 it u,v; 15 for(it i=1;i<=n;++i) fr(g[i][0]); 16 for(it i=1;i<n;++i) fr(u),fr(v),f[v][0]=u; 17 for(it j=1;j<=17;++j) 18 for(it i=1;i<=n;++i) 19 f[i][j]=f[f[i][j-1]][j-1],g[i][j]=g[i][j-1]+g[f[i][j-1]][j-1]; 20 for(it i=1;i<=n;++i){ 21 u=i,v=0; 22 for(it j=17;v<s&&j>=0;--j) 23 if(g[u][j]+v<=s) v+=g[u][j],u=f[u][j]; 24 ans+=(v==s); 25 } 26 printf("%d",ans); 27 return 0; 28 }