您的位置:首页 > 其它

【约数和公式+DFS】BZOJ3629(JLOI2014)[聪明的燕姿]题解

2017-09-08 22:00 483 查看

题目概述

求约数和为 n 的数有哪些。

解题报告

约数和公式为 ∏p|n(∑pi|npi) ,其中 p 是质数。

然后我们会发现 >n√ 的 p 只有一个,可以考虑枚举每个 p 的个数。

由于要求所有满足条件的数,所以DFS……

数据范围很迷……

示例程序

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long LL;
const int maxn=44721;

int n,p[maxn+5],ans[maxn+5];
bool pri[maxn+5];

void Make(int n)
{
pri[0]=pri[1]=true;
for (int i=2;i<=n;i++)
{
if (!pri[i]) p[++p[0]]=i;
for (int j=1;j<=p[0]&&i*p[j]<=n;j++)
{
pri[i*p[j]]=true;
if (i%p[j]==0) break;
}
}
}
bool is_prime(int x)
{
if (x<=maxn) return !pri[x];
for (int i=1,S=sqrt(x);p[i]<=S;i++) if (x%p[i]==0) return false;
return true;
}
void Dfs(int lst=0,int now=n,int Tot=1)
{
if (now==1) {ans[++ans[0]]=Tot;return;}
if ((!lst||now-1>p[lst])&&is_prime(now-1)) ans[++ans[0]]=Tot*(now-1);
for (int i=lst+1,S=sqrt(now);p[i]<=S;i++)
for (LL a=p[i],b=p[i]+1;b<=now;a*=p[i],b+=a)
if (now%b==0) Dfs(i,now/b,Tot*a);
}
int main()
{
freopen("program.in","r",stdin);
freopen("program.out","w",stdout);
Make(maxn);
while (scanf("%d",&n)!=EOF)
{
ans[0]=0;Dfs();sort(ans+1,ans+1+ans[0]);
printf("%d\n",ans[0]);
for (int i=1;i<=ans[0];i++)
if (i==ans[0]) printf("%d\n",ans[i]); else printf("%d ",ans[i]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: