bzoj 4401 块的计数 思想+模拟+贪心

Posted Kaiser

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 4401 块的计数 思想+模拟+贪心相关的知识,希望对你有一定的参考价值。

块的计数

Time Limit: 10 Sec  Memory Limit: 256 MB
Submit: 455  Solved: 261
[Submit][Status][Discuss]

Description

小Y最近从同学那里听说了一个十分牛B的高级数据结构——块状树。听说这种数据结构能在sqrt(N)的时间内维护树上的各种信息,十分的高效。当然,无聊的小Y对这种事情毫无兴趣,只是对把树分块这个操作感到十分好奇。他想,假如能把一棵树分成几块,使得每个块中的点数都相同该有多优美啊!小Y很想知道,能有几种分割方法使得一棵树变得优美。小Y每次会画出一棵树,但由于手速太快,有时候小Y画出来的树会异常地庞大,令小Y感到十分的苦恼。但是小Y实在是太想知道答案了,于是他找到了你,一个天才的程序员,来帮助他完成这件事。

Input

  第一行一个正整数N,表示这棵树的结点总数,接下来N-1行,每行两个数字X,Y表示编号为X的结点与编号为Y的结点相连。结点编号的范围为1-N且编号两两不同。

Output

一行一个整数Ans,表示所求的方案数。

Sample Input

6
1 2
2 3
2 4
4 5
5 6

Sample Output

3

HINT

 

100%的数据满足N<=1000000。

 

Source

 

 首先随便选一个根进行dfs得到size[x]表示以x为根节点的子树的大小。然后我们假设答案为t,需要判断t是否可行。首先显然需要t|n。

显然每一个块有且仅有一个根,定义为这个块的最高点。然后我们发现一个点x是块的根的必要条件是t|size[x]!这个是显然的。然后我

们统计有多少个size[x]被t整除,如果与n/t相同则合法,否则一定小于n/t,因此一定不合法。

 1 #include<cstring>
 2 #include<cmath>
 3 #include<algorithm>
 4 #include<iostream>
 5 #include<cstdio>
 6 
 7 #define N 1000007
 8 #define ll long long
 9 
10 using namespace std;
11 inline int read()
12 {
13     int x=0,f=1;char ch=getchar();
14     while (ch<0||ch>9){if (ch==-)f=-1;ch=getchar();}
15     while (ch>=0&&ch<=9){x=x*10+ch-0;ch=getchar();}
16     return x*f;
17 }
18 
19 int n,ans;
20 int Head[N],ret[N<<1],Next[N<<1],tot;
21 int size[N],st[N];
22 
23 inline void ins(int u,int v)
24 {
25     ret[++tot]=v;
26     Next[tot]=Head[u];
27     Head[u]=tot;
28 }
29 void dfs(int u,int f)
30 {
31     size[u]=1;
32     for (int i=Head[u];i;i=Next[i])
33     {
34         if (ret[i]==f) continue;
35         dfs(ret[i],u);
36         size[u]+=size[ret[i]];
37     }
38     st[size[u]]++;
39 }
40 int main()
41 {
42     n=read();
43     for (int i=1;i<n;i++)
44     {
45         int u=read(),v=read();
46         ins(u,v);ins(v,u);
47     }
48     dfs(1,0);
49     for (int i=1;i<=n;i++)
50         if (n%i==0)
51         {
52             int sum=0;
53             for (int j=i;j<=n;j+=i)
54                 sum+=st[j];
55             if (sum==n/i) ans++;
56         }
57     printf("%d\n",ans);
58 }

 

以上是关于bzoj 4401 块的计数 思想+模拟+贪心的主要内容,如果未能解决你的问题,请参考以下文章

bzoj 4401: 块的计数

bzoj4401块的计数(水dfs)

bzoj4401块的计数 结论题

bzoj 2563 贪心 思想

Kruskal+贪心思想BZOJ3624-[Apio2008]免费道路

BZOJ2457[BeiJing2011]双端队列 贪心+模拟