bzoj3629 / P4397 [JLOI2014]聪明的燕姿

P4397 [JLOI2014]聪明的燕姿

根据唯一分解定理

$n=q_{1}^{p_{1}}*q_{2}^{p_{2}}*q_{3}^{p_{3}}*......*q_{m}^{p_{m}}$

而$n$的约数和为$\prod_{i=1}^{m} \sum_{j=0}^{p_{i}}q_{i}^j$

于是我们可以暴搜枚举每个约数的个数,而且只要枚举到$\sqrt{S}$

tips:注意最后一个数字后不带空格

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #define re register
 6 using namespace std;
 7 #define N 100010
 8 int n,v[N],pri[N],cct,ans[N],ttp;
 9 bool check(int x){//判断x是否是素数
10     if(x<N) return v[x]==x;
11     for(int i=1;i<=cct&&pri[i]*pri[i]<=x;++i)
12         if(x%pri[i]==0) return 0;
13     return 1;
14 }
15 void dfs(int la,int s,int tt){
16     if(tt==1){ans[++ttp]=s;return;}
17     if(tt-1>pri[la]&&check(tt-1)) ans[++ttp]=s*(tt-1);//可以表示成某个未搜过的素数+1
18     for(int i=la+1;i<=cct&&pri[i]*pri[i]<=tt;++i)
19         for(int j=pri[i]+1,u=pri[i];j<=tt;u*=pri[i],j+=u)
20             if(tt%j==0) dfs(i,s*u,tt/j);
21 }
22 int main(){
23     for(re int i=2;i<N;++i){
24         if(!v[i]) v[i]=pri[++cct]=i;
25         for(re int j=1;j<=cct;++j){
26             if(pri[j]>i||pri[j]*i>=N) break;
27             v[pri[j]*i]=pri[j];
28         }
29     }
30     while(scanf("%d",&n)!=EOF){
31         ttp=0;dfs(0,1,n);
32         printf("%d\n",ttp);
33         sort(ans+1,ans+ttp+1);
34         for(int i=1;i<=ttp;++i)
35             printf("%d%c",ans[i],i==ttp?'\n':' ');//注意格式
36     }return 0;
37 }
View Code

 

posted @ 2018-11-02 22:00  kafuuchino  阅读(174)  评论(0编辑  收藏  举报