【约数和公式+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; }
相关文章推荐
- BZOJ 3629 JLOI2014 聪明的燕姿 约数和+DFS
- [bzoj3629][JLOI2014]聪明的燕姿(数论+dfs)
- bzoj 3629 [JLOI2014]聪明的燕姿(约数和,搜索)
- bzoj3629 [JLOI2014]聪明的燕姿(数论+dfs)
- bzoj 3629: [JLOI2014]聪明的燕姿 (dfs+线性筛)
- 3629: [JLOI2014]聪明的燕姿|约数和|DFS
- BZOJ 3629 [JLOI2014] 聪明的燕姿 dfs
- BZOJ 3629 JLOI2014 聪明的燕姿 约数和+DFS
- BZOJ_3629_[JLOI2014]聪明的燕姿_dfs
- 【BZOJ3629】【JLOI2014】聪明的燕姿 dfs 素数筛
- [暴力搜索 剪枝 约数和反函数] BZOJ 3629 [JLOI2014]聪明的燕姿
- BZOJ 3629 [JLOI 2014]聪明的燕姿 简单数论
- 【BZOJ3629】[JLOI2014]聪明的燕姿【质因数分解】【暴搜】
- 【BZOJ3629】[JLOI2014]聪明的燕姿 数学+搜索
- BZOJ 3629&&JLOI2014 聪明的燕姿
- bzoj3629: [JLOI2014]聪明的燕姿 搜索好题
- bzoj 3629: [JLOI2014]聪明的燕姿
- Bzoj3629--Jloi2014聪明的燕姿
- BZOJ3629 [JLOI2014]聪明的燕姿
- [BZOJ 3629][ JLOI2014 ]聪明的燕姿