1. 程式人生 > >洛谷P4397 [JLOI2014]聰明的燕姿

洛谷P4397 [JLOI2014]聰明的燕姿

moto pre 哪裏 聰明的燕姿 深度 等於 top printf scan

傳送門

dfs的時候莫名其妙深度太大過不了……然後死活找不出哪裏錯……

首先,約數和這東西是個積性函數,或者直接點的話就是如果$$n=p_1^{a_1}p_2^{a_2}p_3^{a_3}…p_m^{a_m}$$

那麽$n$的約數和就等於$$S=\begin{matrix} \prod_{i=1}^m \end{matrix}\begin{matrix} \sum_{j=0}^{a_i} {p_i}^j \end{matrix}$$
然後因為最近剛學過等比數列求和公式我就把這東西往那方面去想了……然後一直爆零……

實際上只要爆搜就可以了……我太蠢了……

記得dfs的時候如果搜到$S-1$是質數的之後直接乘上去就好了,不用繼續搜

 1 //minamoto
 2 #include<bits/stdc++.h>
 3 #define ll long long
 4 using namespace std;
 5 const int N=1e5;
 6 int p[N+5],vis[N+5],m,st[N<<2],top,n,q;
 7 void init(){
 8     for(int i=2;i<=N;++i){
9 if(!vis[i]) p[++m]=i; 10 for(int j=1;j<=m&&i*p[j]<=N;++j){ 11 vis[i*p[j]]=1; 12 if(i%p[j]==0) break; 13 } 14 } 15 } 16 bool check(int x){ 17 if(x==1) return 0;if(x<=N) return !vis[x]; 18 for(int i=1;p[i]*p[i]<=x;++i) if
(x%p[i]==0) return 0; 19 return 1; 20 } 21 void dfs(ll now,int x,ll y){ 22 if(now==1) return (void)(st[++top]=y); 23 if(now-1>=p[x]&&check(now-1)) st[++top]=y*(now-1); 24 for(int i=x;1ll*p[i]*p[i]<=now;++i){ 25 ll tmp=p[i],pp=p[i]+1; 26 for(;pp<=now;tmp*=p[i],pp+=tmp) 27 if(now%pp==0) dfs(now/pp,i+1,y*tmp); 28 } 29 } 30 int main(){ 31 // freopen("testdata.in","r",stdin); 32 init(); 33 while(~scanf("%d",&n)){ 34 top=0; 35 dfs(n,1,1); 36 sort(st+1,st+1+top); 37 printf("%d\n",top); 38 for(int i=1;i<=top;++i) printf("%d%c",st[i]," \n"[i==top]); 39 } 40 return 0; 41 }

洛谷P4397 [JLOI2014]聰明的燕姿