聪明的燕姿题解
题意
给出一个数
分析
约数和定理
我们知道,求一个数
预处理出质数和,我们再枚举
把
这里有一个小细节,统计答案时不是要把最大加数都乘起来吗,这里所以的最大加数都要相互互质,不然就会出现
代码
#include<bits/stdc++.h>
using namespace std;
long long gcd(long long x,long long y){return y?gcd(y,x%y):x;}
//prime 筛质数
int prime[10000]={0},pn=0;
void getprime()
{
bool is_prime[50000]={0};
for(int i=2;i<=50000;i++)
{
if(!is_prime[i]) prime[++pn]=i;
for(int j=1;j<=pn&&prime[j]*i<=50000;j++)
{
is_prime[prime[j]*i]=1;
if(!(i%prime[j])) break;
}
}
}
//isprime 判断质数
bool isprime(long long x)
{
for(int i=2;i<=sqrt(x);i++)
if(!(x%i)) return 0;
return 1;
}
//Map 用Map记录下可以分成 1+p+p^2... 的数
map<long long,vector<long long> > Map;
void getMap()
{
for(long long i=1,sum,power;i<=pn;i++)
{
power=prime[i];
sum=1+power;
while(sum<=2e9)
{
Map[sum].push_back(power);
power*=prime[i];
sum+=power;
}
}
}
//ans
long long ans[100000]={0},ansn=0,final_ans[100000]={0};
//div div是S的约数,同时这个约数要满足可以分成 1+p+p^2...
long long S,sqrt_S;
int S_div[50000]={0},dn=0;
void getdiv()
{
for(long long i=1;i<=sqrt_S;i++)
{
if(!(S%i))
{
if(Map.find(i)!=Map.end()) S_div[++dn]=i;
if(i!=S/i&&Map.find(S/i)!=Map.end()) S_div[++dn]=S/i;
}
}
sort(S_div+1,S_div+1+dn);
}
//put q into ans
vector<int> q;
void putout(long long prod,int p)
{
if(p>=q.size())
{
return (void)(ans[++ansn]=prod);
}
for(int i=0;i<Map[q[p]].size();i++)
if(gcd(prod,Map[q[p]][i])==1)
putout(prod*Map[q[p]][i],p+1);
}
//q ( q 为队列,因为有些数会被分成不同的 1+p+p^2... 所以要加入队列中用 putout 遍历一遍)
void getq(int now_S,int now_div)
{
if(now_S==1) return putout(1,0);
for(int i=now_div;i<=dn;i++)
{
if(now_S<S_div[i]) break;
if(now_S%S_div[i]==0)
{
q.push_back(S_div[i]);
getq(now_S/S_div[i],i+1);
q.pop_back();
}
}
if(now_S>sqrt_S&&isprime(now_S-1)) putout(now_S-1,0);
}
int main()
{
getprime();
getMap();
while(cin>>S)
{
memset(ans,0,sizeof(ans));
memset(S_div,0,sizeof(S_div));
dn=0;
ansn=0;
sqrt_S=sqrt(S);
getdiv();
getq(S,1);
sort(ans+1,ans+1+ansn); //将答案排序
long long *p=unique(ans+1,ans+1+ansn); //去重
ansn=0;
for(long long *i=&ans[1];i!=p;i++,ansn++); //统计个数
cout<<ansn<<endl;
for(long long *i=&ans[1];i!=p;i++) //输出
{
cout<<*i;
if(i+1!=p) cout<<" ";
else cout<<endl;
}
}
}