#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define N 100000
int p[N+5],cnt,s,ans,num[N+5];
bool flag[N+5];
void getprime()
{
for(int i=2;i<=N;i++)
{
if(!flag[i]) p[++cnt]=i;
for(int j=1; i*p[j]<=N; j++)
{
flag[i*p[j]]=1;
if(i%p[j]==0) break;
}
}
}
bool isprime(int x)
{
if(x==1) return false;
if(x<=N) return !flag[x];
for(int i=1;p[i]*p[i]<=x;i++)
if(x%p[i]==0) return false;
return true;
}
void dfs(int last,int now,int tot)
{
if(tot==1){ num[++ans]=now; return; }
if(tot-1>p[last]&&isprime(tot-1))
num[++ans]=now*(tot-1);
for(int i=last+1; p[i]*p[i]<=tot; i++)
for(int tnum=p[i]+1,t=p[i]; tnum<=tot; t*=p[i],tnum+=t)
if(tot%tnum==0)
dfs(i,now*t,tot/tnum);
}
int main()
{
getprime();
while(scanf("%d",&s)!=EOF)
{
ans=0;
dfs(0,1,s);
cout<<ans<<endl;
sort(num+1,num+ans+1);
for(int i=1; i<=ans; i++)
printf("%d%c",num[i],i==ans?'\n':' ');
}
}
【BZOJ3629】[JLOI2014]聰明的燕姿 數學+搜索
我遇見誰會有怎樣的對白
我等的人他在多遠的未來
我聽見風來自地鐵和人海
我排着隊拿着愛的號碼牌
——孫燕姿《遇見》
題意:給出一個數S,求約數和等於S的數。
作爲一道數學題,首先需要了解一些數學定理:
算數基本定理:
任何一個大於1的自然數N,都可以唯一分解成有限個質數的乘積N=P₁^a₁ P₂^a₂…Pn^an,這裏P₁<P₂<…<Pn均爲質數,其諸指數ai是正整數。
這樣的分解稱爲N的標準分解式。
約數和定理:
對於任意一個大於1的正整數N可以分解正整數:N=P₁^a₁ P₂^a₂…Pn^an,則由約數個數定理可知N的正約數有(a₁+1)(a₂+1)(a₃+1)…(an+1)個,那麼N的(a₁+1)(a₂+1)(a₃+1)…(an+1)個正約數的和爲f(N)=(P₁^0+P₁^1+P₁^2+…P₁^a₁)(P₂^0+P₂^1+P₂^2+…P₂^a₂)…(Pn^0+Pn^1+Pn^2+…Pn^an)。
至此,搜索算法很顯然地露出水面——窮舉Pi及其對應的ai進行搜索。
①若當前數可表示成一個並未搜索過的質數與1的和,則之前搜索過的數與這個質數的乘積符合題意。
②對於每一個未被搜索過且平方小於當前數的質數,則枚舉所有可能符合題意的ai進行遞歸搜索。
這樣,此題便被完美解決。
【吐槽】當時JLOI時由於考場內由於臺式機與投影儀的連接出現問題,評測機是一個臨時借來的筆記本電腦——CPU慢得很恐怖,令我的卡時限的暴搜直接不解釋地TLE……
順便希望我所等待的那個人早日到來!!!
後來發生了一個慘(xi)絕(da)人(pu)寰(ben)的事情,這份代碼被同屋的大神在時間上超越了……於是******,終於重奪 Rank 1~~時間僅用80ms~~
[JLOI2014]聰明的燕姿 C++代碼:
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.