设M(x)为x的约数和,那么考虑约数和的求法,约数和显然是一个积性函数。
设
那么
M(x)=∑c1=0t1pc11∗∑c2=0t2pc22∗∑c3=0t3pc33∗......∗∑cn=0tnpcnn
这样就可以考虑枚举质因子DFS转化为子问题继续求解。
dfs(now,pos,rest)是指搜索枚举到第pos个质因子,当前值为now,然后剩余的因子的和为rest时的解
搜索时枚举≤n−√的质因子,并且单独判断rest−1是否为质数,这样可以保证搜出来的解没有重复。
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<vector>
#include<cmath>
#include<complex>
#include<queue>
#include<map>
#include<set>
#define N 45000
#define ll long long
using namespace std;
int top,a[N],prime[N],ans[N];
int n,tot;
void get_prime()
{
for(int i=2;i<N;i++)
{
if(!a[i])
prime[++top]=i;
for(int j=1;prime[j]*i<N;j++)
{
a[prime[j]*i]=1;
if(i%prime[j]==0)break;
}
}
}
bool jud(int x)
{
if(x==1)return 0;
for(int i=1;prime[i]*prime[i]<=x;i++)
if(x%prime[i]==0)return 0;
return 1;
}
void dfs(int now,int pos,int rest)
{
if(rest==1)
{
ans[++tot]=now;
return;
}
if(rest-1>=prime[pos]&&jud(rest-1))
ans[++tot]=(rest-1)*now;
for(int i=pos;prime[i]*prime[i]<=rest;i++)
for(ll p=prime[i],sum=p+1;sum<=rest;p*=prime[i],sum+=p)
if(rest%sum==0)
dfs(now*p,i+1,rest/sum);
}
int main()
{
get_prime();
while(scanf("%d",&n)!=EOF)
{
tot=0;
dfs(1,1,n);
sort(ans+1,ans+tot+1);
printf("%d\n",tot);
for(int i=1;i<=tot;i++)
printf("%d%c",ans[i],i==tot?'\n':' ');
}
return 0;
}