洛谷P4397 [JLOI2014]聪明的燕姿

传送门

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 }

猜你喜欢

转载自www.cnblogs.com/bztMinamoto/p/9824476.html