Description
小Y最近从同学那里听说了一个十分牛B的高级数据结构——块状树。听说这种数据结构能在sqrt(N)的时间内维护树上的各种信息,十分的高效。当然,无聊的小Y对这种事情毫无兴趣,只是对把树分块这个操作感到十分好奇。他想,假如能把一棵树分成几块,使得每个块中的点数都相同该有多优美啊!小Y很想知道,能有几种分割方法使得一棵树变得优美。小Y每次会画出一棵树,但由于手速太快,有时候小Y画出来的树会异常地庞大,令小Y感到十分的苦恼。但是小Y实在是太想知道答案了,于是他找到了你,一个天才的程序员,来帮助他完成这件事。
100%的数据满足N<=1000000。
Solution
很有意思的水题
考虑枚举答案x,我们发现x一定是n的约数,并且一定有n/x个节点的size是x的倍数
注意到我们可以开一个桶然后枚举答案的倍数计数,这样就是nlogn的了
Code
#include <stdio.h>
#include <string.h>
#define rep(i,st,ed) for (int i=st;i<=ed;++i)
const int N=1000005;
struct edge {int y,next;} e[N*2];
int size[N],ls[N],rec[N],edCnt,n;
int read() {
int x=0,v=1; char ch=getchar();
for (;ch<'0'||ch>'9';v=(ch=='-')?(-1):(v),ch=getchar());
for (;ch<='9'&&ch>='0';x=x*10+ch-'0',ch=getchar());
return x*v;
}
void add_edge(int x,int y) {
e[++edCnt]=(edge) {y,ls[x]}; ls[x]=edCnt;
e[++edCnt]=(edge) {x,ls[y]}; ls[y]=edCnt;
}
void dfs(int now,int fa) {
size[now]=1;
for (int i=ls[now];i;i=e[i].next) {
if (e[i].y!=fa) {
dfs(e[i].y,now); size[now]+=size[e[i].y];
}
}
rec[size[now]]++;
}
int calc(int x) {
int cnt=0;
for (int i=x;i<=n;i+=x) {
cnt+=rec[i];
}
return (cnt==n/x);
}
int main(void) {
n=read(); int ans=0;
rep(i,2,n) add_edge(read(),read());
dfs(1,0);
for (int i=1;i*i<=n;++i) if (n%i==0) {
ans+=calc(i)+calc(n/i)*(i*i!=n);
}
printf("%d\n", ans);
return 0;
}