丧心病狂
利用欧拉函数的公式实现逆推
然后
其中附带了一点素数判断[Miller-Rabin]
总之很麻烦
φ(n)=n×(p1−1)×(p2−1)…(px−1)p1×p2×…px
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<vector>
#include<climits>
#include<string>
#include<cstdlib>
#include<ctime>
#define D 10000000
#define MOD 1000000007
#define LL long long
using namespace std;
LL prime[10000005],primenum[10000005],cnt,tot,n,ans[10000005];
LL Rand(LL p)
{
return (((LL)rand()<<31)|rand())%(p-1)+1;
}
void pre()
{
prime[1]=1;
LL i,j;
for(i=2;i<=10000000;i++)
{
if(!prime[i])
{
tot++;
primenum[tot]=i;
}
for(j=1;j<=tot&&i*primenum[j]<=10000000;j++)
{
prime[i*primenum[j]]=1;
if(i%primenum[j]==0) break;
}
}
}
LL mul(LL a,LL b,LL mod)
{
LL tmp=0;
while(b)
{
if(b&1) tmp=(tmp+a)%mod;
a=(a+a)%mod;
b>>=1;
}
return tmp;
}
LL pow(LL a,LL b,LL mod)
{
LL tmp=1;
while(b)
{
if(b&1) tmp=mul(tmp,a,mod);
a=mul(a,a,mod);
b>>=1;
}
return tmp;
}
bool check(LL p)
{
LL x=p-1,y,z,k=0;
while(!(x&1))
{
x>>=1;
k++;
}
for(LL i=1;i<=5;i++)
{
y=pow(Rand(p),x,p);
for(LL j=1;j<=k;j++)
{
z=mul(y,y,p);
if((z==1)&&(y!=1)&&(y!=p-1)) return 0;
y=z;
}
if(y!=1) return 0;
}
return 1;
}
void dfs(LL d,LL x,LL res)
{
LL i;
if(x==1)
{
cnt++;
ans[cnt]=res;
return;
}
if(x+1>primenum[tot]&&check(x+1))
{
cnt++;
ans[cnt]=res*(x+1);
}
LL tx=x,tres=res,s;
for(i=d;i>=1;i--)
if(tx%(primenum[i]-1)==0)
{
x=tx/(primenum[i]-1);
res=tres;
s=1;
while(1)
{
if(x%s!=0) break;
res*=primenum[i];
dfs(i-1,x/s,res);
s=s*primenum[i];
}
}
}
int main()
{
freopen("arc.in","r",stdin);
freopen("arc.out","w",stdout);
LL i,k,t;
pre();
scanf("%lld%lld",&n,&k);
dfs(tot,n,1);
sort(ans+1,ans+cnt+1);
for(i=1;i<=k;i++)
printf("%lld ",ans[i]);
return 0;
}