题解[JLOI2012]树

题目:
P3252 [JLOI2012]树

比较巧妙地统计路径长度。直接用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 }
View Code

 

原文地址:https://www.cnblogs.com/Kylin-xy/p/11652194.html