您的位置:首页 > 其它

2017.9.26 块的计数 思考记录

2017-09-26 23:25 141 查看
这种题就属于那种描述很简单,要求很简单,但就是无从下手的题

这个题我只有n根n做法、、枚举因数检验。。

首先对于任何块的大小,方案唯一,这是显然的,,如果划分位置改变1,一定有一个位置+1,一个位置-1,不符题意

然后我们还需要发现一个性质,如果能分成大小为n的块,子树节点数的数量是n的倍数的数量一定为总点数/n

证明其实也不难,关键是想不到、其实思考划分问题我们可以只考虑特殊点,对于一些点的不确定可以转化为只讨论确定的点

因为点的sz统计是不重复的,所以如果出现了sz为n的倍数的点,则说明两两之间至少有n个点不同

而所有点都能被划分,所以如果总点数/n==sz是n的倍数的节点个数,说明n/i*n个点都被分配到块里了,满足题意

码:

#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
#define N 1000005
int i,sz
,ans,a,b,tong
,n,j;
vector<int>v
;
void dfs(int o,int fa)
{
int i;
sz[o]=1;
for(i=0;i<v[o].size();i++)
{
int nd=v[o][i];
if(nd==fa)continue;
dfs(nd,o);
sz[o]+=sz[nd];
}
tong[sz[o]]++;
}
int main()
{
scanf("%d",&n);
for(i=1;i<n;i++)
{
scanf("%d%d",&a,&b);
v[a].push_back(b);
v[b].push_back(a);
}
dfs(a,0);
for(i=1;i<=n;i++)
{
if(n%i)continue;
int o=0;
for(j=i;j<=n;j+=i)
{
o+=tong[j];
}
if(o==n/i)ans++;
}
printf("%d",ans);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: