标签:pass 正整数 size span inpu pac space scanf ++
写完这道题感觉人生都是灰暗的。。。
不存在的!!!数学学得好就知道自己等的人是谁?
这是不不不不不可能的!!!我到现在都没有女朋友!!!
阴天傍晚车窗外
未来有一个人在等待
向左向右向前看
爱要拐几个弯才来
我遇见谁会有怎样的对白
我等的人他在多远的未来
我听见风来自地铁和人海
我排着队拿着爱的号码牌
城市中人们总是拿着号码牌,不停寻找,不断匹配,可是谁也不知道自己等的那个人是谁。可是燕姿不一样,燕姿知道自己等的人是谁,因为燕姿数学学得好!燕姿发现了一个神奇的算法:假设自己的号码牌上写着数字S,那么自己等的人手上的号码牌数字的所有正约数之和必定等于S。
Input
Output
这道题异常明显考到了约数和定理。。。
完全搞不清省选题怎么会考小学奥数。。。
证明一下:
已知一个正整数n,就可以得到n=(p1^k1)*(p2^k2*)*......*(pm^km);
其中pi(1<=i<=m)是质数,也就是n的质因数。。。
将每一个(pi^ki)分成若干个不同因数:(pi^0),(pi^1),.....,(pi^ki);
于是得到n因数的个数f[n]=(1+k1)*(1+k2)*......*(1+km);
而n所有因数和h[n]=(1+p1^1+p1^2+...+p1^k1)*(1+p2^1+p2^2+...+p2^k2)*....*(1+pm^1+pm^2+...+pm^km);
知道这个定理后,只要深搜就能很容易做出这道题。。。
注意题目中s范围很大,一定要剪枝。。。
#include<cstdio>
#include<iostream>
#include<algorithm>
#define LL long long
#define M 100100
using namespace std;
LL n,p[M],ans[M],tot;
bool not_pri[M];
void get_pri(){
int i,j;
for(i=2;i<=100000;i++){
if(!not_pri[i])
p[++p[0]]=i;
for(j=1;p[j]*i<=100000&&j<=p[0];j++){
not_pri[p[j]*i]=1;
if(i%p[j]==0) break;
}
}
}
bool judge_pri(LL x){
LL i;
if(x==1)
return 0;
for(i=1;p[i]*p[i]<=x;i++)
if(x%p[i]==0)
return 0;
return 1;
}
void dfs(LL now,int pos,LL left){
int i;
if(left==1){
ans[++ans[0]]=now;
return;
}
if(left-1>=p[pos]&&judge_pri(left-1))
ans[++ans[0]]=(left-1)*now;
for(i=pos;p[i]*p[i]<=left;i++){
LL power_sum=p[i]+1;
LL power=p[i];
for(;power_sum<=left;power*=p[i],power_sum+=power)
if(left%power_sum==0)
dfs(now*power,i+1,left/power_sum);
}
}
int main(){
int i;
get_pri();
while(scanf("%lld",&n)==1){
ans[0]=0;
tot=0;
dfs(1,1,n);
sort(ans+1,ans+ans[0]+1);
printf("%lld\n",ans[0]);
for(i=1;i<=ans[0];i++)
printf("%lld%c",ans[i],i==ans[0]?‘\n‘:‘ ‘);
}
return 0;
}
This passage is made by Yukino.
标签:pass 正整数 size span inpu pac space scanf ++
原文地址:http://www.cnblogs.com/Yuigahama/p/7401132.html