bzoj4401 块的计数
首先确定一个根后dfs一遍,统计出每个子树的点数个数,然后枚举n的因子x,统计多少子树的点数个数是当前枚举因子x的倍数,如果有n/x个子树满足条件,则答案+1
代码
1 #include<cstdio> 2 #include<algorithm> 3 #include<set> 4 #define fi first 5 #define sc second 6 #define mp make_pair 7 #define N 2000100 8 using namespace std; 9 int p[N],pre[N],tt[N],s[N],cnt[N]; 10 int n,i,a,b,j,ans,dp,sum; 11 void link(int x,int y) 12 { 13 dp++;pre[dp]=p[x];p[x]=dp;tt[dp]=y; 14 } 15 void dfs(int x,int fa) 16 { 17 int i=p[x]; 18 s[x]=1; 19 while (i) 20 { 21 if (tt[i]!=fa) 22 { 23 dfs(tt[i],x); 24 s[x]+=s[tt[i]]; 25 } 26 i=pre[i]; 27 } 28 } 29 int main() 30 { 31 scanf("%d",&n); 32 for (i=1;i<n;i++) 33 { 34 scanf("%d%d",&a,&b); 35 link(a,b); 36 link(b,a); 37 } 38 dfs(1,0); 39 for (i=1;i<=n;i++) 40 cnt[s[i]]++; 41 for (i=1;i<=n;i++) 42 if (n%i==0) 43 { 44 sum=0; 45 for (j=i;j<=n;j+=i) 46 sum+=cnt[j]; 47 if (sum==n/i) ans++; 48 } 49 printf("%d\n",ans); 50 }