count

这里写图片描述
这里写图片描述
1s    256M
这题的解法好巧妙。
我们可以通过dfs来处理一个 f 数组。f[i]表示以i为根的子树有多少个节点。
那么当我们从1到n枚举每个块的大小时(n%i==0),然后扫一遍 f 数组,f[]为 i 的倍数的个数如果等于n/i,那么就是一种成功的方案。

#include<iostream>
#include<cstring>
#include<cstdio>
#define LL long long
#define N 1000009
using namespace std;
int n,ans;
int head[N],nxt[2*N],to[2*N],cnt;
int f[N];//记录以i为根的子树有多少个节点 
bool vis[N];
void add(int x,int y)
{
    to[++cnt]=y;
    nxt[cnt]=head[x];
    head[x]=cnt;
}
int dfs(int x)
{
    vis[x]=1;
    int tot=0;
    for(int i=head[x];i;i=nxt[i])
    {
        if(!vis[to[i]]) 
        {
            vis[to[i]]=1;
            tot+=f[to[i]]?f[to[i]]:f[to[i]]=dfs(to[i]);
        }
    }
    return tot+1;
}
bool check(int x)
{
    int tot=0;
    for(int i=1;i<=n;i++)
    if(f[i]%x==0) tot++;
    return tot==(n/x);
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<n;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        add(x,y);add(y,x);
    }
    f[1]=dfs(1);
    for(int i=1;i<=n;i++)
    if(n%i==0) ans+=check(i);
    printf("%d\n",ans);
    return 0;
}
原文地址:https://www.cnblogs.com/dfsac/p/7587801.html