bzoj3629 / P4397 [JLOI2014]聪明的燕姿

Posted kafuuchino

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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
",ttp);
33         sort(ans+1,ans+ttp+1);
34         for(int i=1;i<=ttp;++i)
35             printf("%d%c",ans[i],i==ttp?
: );//注意格式
36     }return 0;
37 }
View Code

 

以上是关于bzoj3629 / P4397 [JLOI2014]聪明的燕姿的主要内容,如果未能解决你的问题,请参考以下文章

bzoj千题计划297:bzoj3629: [JLOI2014]聪明的燕姿

bzoj 3629 [JLOI2014]聪明的燕姿——约数和定理+dfs

bzoj 3629: [JLOI2014]聪明的燕姿线性筛+dfs

BZOJ 3629 JLOI2014 聪明的燕姿 约数和+DFS

P4397 [JLOI2014]聪明的燕姿

icodelab 找朋友(P4397 [JLOI2014]聪明的燕姿)