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 }

原文地址:https://www.cnblogs.com/fengzhiyuan/p/8168797.html

时间: 2025-01-13 15:20:15

bzoj 4401 块的计数 思想+模拟+贪心的相关文章

bzoj 4401: 块的计数

根据块状树的那堆理论可以发现,对于某种块大小,可行的分法只有一种 如果一个点能被当成块顶,仅当其子树大小是块大小的倍数 于是枚举块的大小\(i\),当可行的块顶个数大于等于\(n / i\)时,就可以构造出可行的分法了 时间复杂度 \(O(\sum_{d|n}d)\) #include <bits/stdc++.h> #define N 2010000 using namespace std; int n; int lt[N], bi[N], nt[N], tl; int si[N], ai[

BZOJ 2111 Perm 排列计数(满二叉树)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2111 题意:求1到n有多少种排列满足:A[i]>A[i/2](2<=i<=n). 思路:形式类似二叉树.建模之后其实就是n个节点的不同的满二叉树有多少种?用f[i]表示i个节点的满二叉树个数,则f[n]=f[L]*f[R]*C(n-1,L).其中L和R对于确定的n来说是确定的.比如n=10时,左右子树分别有6.3个点. i64 a[N],n,p,f[N]; void init(

HDU 4903 (模拟+贪心)

Fighting the Landlords Problem Description Fighting the Landlords is a card game which has been a heat for years in China. The game goes with the 54 poker cards for 3 players, where the “Landlord” has 20 cards and the other two (the “Farmers”) have 1

77.JAVA编程思想——模拟垃圾回收

77.JAVA编程思想--模拟垃圾回收 这个问题的本质是若将垃圾丢进单个垃圾筒,事实上是未经分类的.但在以后,某些特殊的信息必须恢复,以便对垃圾正确地归类.在最开始的解决方案中,RTTI 扮演了关键的角色.这并不是一种普通的设计,因为它增加了一个新的限制.正是这个限制使问题变得非常有趣--它更象我们在工作中碰到的那些非常麻烦的问题.这个额外的限制是:垃圾抵达垃圾回收站时,它们全都是混合在一起的.程序必须为那些垃圾的分类定出一个模型.这正是RTTI 发挥作用的地方:我们有大量不知名的垃圾,程序将正

UVA-11054-Wine trading in Gergovia(模拟+贪心)

首先这道题的节点数太多了,达到10^5,所以不能用数组模拟啊,肯定TLE,所以用贪心算法,读取第一个结点,搬到第二个结点,剩下的和第二个结点合并,一起搬到第三个结点......这个算法很好,每次看成只是邻居间买卖,下面是代码: #include<stdio.h> #include<iostream> #include<stdlib.h> using namespace std; int main() { int n; while(cin>>n &&a

块奖励计数及其状态平衡

一.EOS的奖励制度??对记账节点的经济激励机制是区块链项目不可缺少的重要组成部分,EOS则是通过增发的方式来给予节点奖励,支付其工资.每年增发的EOS比率为5%左右,按照总供应量10亿来计算,就是五千万EOS. 通胀的EOS用途: ??如上图,通胀的EOS币先发行到系统账户eosio中,其中的20%, 用于节点奖励:另外80%,用于EOS基金池,会在未来用于社区福利应用或者对EOS系统有所帮助的项目.该部分资金存入eosio.saving系统账户中.??EOS节点分为两类:出块节点(Block

计数思想(类似于hash值)

//判断数组中是否有重复元素,最直接的思路是用双层循环判断(O(n ^ 2)); //也可以先排序,后比较,但基于比较的排序时间复杂度至少为O(n*logn).//所以,这些思路都不行.根据题目的限制条件,很容易想到用计数排序,时间复杂度为O(n),这当然满足题意,但是,把计数排序用在此处,无疑是大材小用了.//在计数排序中,有一个关键的步骤是计数,本题就可以利用计数排序中的计数思想(有点类似于哈希),程序代码如下: #include<iostream>using namespace std;

Codeforces 452D [模拟][贪心]

题意: 给你k件衣服处理,告诉你洗衣机烘干机折叠机的数量,和它们处理一件衣服的时间,要求一件衣服在洗完之后必须立刻烘干,烘干之后必须立刻折叠,问所需的最小时间. 思路: 1.按照时间模拟 2.若洗完的衣服或者烘干的衣服较多来不及进行下一个步骤,则从一开始就顺延洗衣服的时间,贪心的思想也是体现在这里. 3.关键在于烘干衣服的顺延如何处理,因为需要调整洗衣服的起始时间,其实我们只要对烘干衣服的时间进行顺延处理就可以了,因为即使没有调整洗衣服的起始时间,那么下次到了烘干衣服的时间的时候因为烘干衣服的数

ACM: NBUT 1105 多连块拼图 - 水题 - 模拟

NBUT 1105  多连块拼图 Time Limit:1000MS     Memory Limit:65535KB     64bit IO Format: Practice Appoint description:  System Crawler  (Aug 12, 2016 9:32:14 AM) Description 多连块是指由多个等大正方形边与边连接而成的平面连通图形. -- 维基百科 给一个大多连块和小多连块,你的任务是判断大多连块是否可以由两个这样的小多连块拼成.小多连块只能