基础数论算法(六) 素数的筛法与质因数分解
2017-08-12 14:50
190 查看
素数筛法
如果我们需要多次判断是不是素数时,比起无数次的枚举、测试,还是提前筛出一张素数表比较好Eratosthenes筛法
一般情况下够用的筛法。复杂度nlnlnn,关键是不容易写错。还有别问我这个复杂度怎么算出来的。实现非常简单。#include <iostream> #include <cstring> using namespace std; #define MAXN 1000001 int main(){ bool notprime[MAXN]; memset(notprime,0,sizeof(notprime)); notprime[1]=1; for(int a=2;a<MAXN;a+=(a==2?1:2)) if(!notprime[a]) //如果不加的话复杂度nlnn for(int k=2;a*k<MAXN;++k) notprime[k*a]=1; for(int i=1;i<MAXN;++i) if(!notprime[i]) cout<<i<<endl; return 0; }
线性筛
又称欧拉筛,复杂度几乎是O(n),甚至直接看成O(n)即可。其秘诀就是保证每个数都是被自己最小的因子筛掉的。它的实现是这样的:对i,分别筛掉i*prime[j],其中prime[j]表示所有小于i的素数的数组。如果prime[k]|i,则直接推出循环,因为该数一定会被其他数筛掉。
在数据比较大的时候,欧拉筛会明显占优势。缺点是容易写错。
#include <iostream> #include <cstring> #define MAXN 14 using namespace std; bool notprime[MAXN]; int prime[MAXN]; int main(){ notprime[1]=true; int count=0; for(int i=2;i<MAXN;++i){ if(!notprime[i]) prime[++count]=i; for(int j=1;j<=count;++j){ if(prime[j]*i>MAXN) break; notprime[prime[j]*i]=true; if(i%prime[j]==0) break; } } for(int i=1;i<MAXN;++i) if(!notprime[i]) cout<<i<<endl; }
欧拉筛的原理我曾经想了一个上午也没有搞懂……所以实在不行就背代码吧。
质因数分解
分解质因数还是很有意义的一件事,实现起来也不算太难。试除法
可以借助筛出的素数分解,这样会降些复杂度,这里就直接写不需要提前筛的算法了。#include <iostream> #include <vector> using namespace std; typedef long long LL; int main(){ LL a; cin>>a; vector<pair<LL,int> > v; vector<pair<LL,int> >::iterator vi; for(int i=2;i*i<=a;i+=(i==2?1:2)){ if(a%i==0){ int count=0; while(a%i==0) ++count,a/=i; v.push_back(make_pair(i,count)); } } if(a!=1) v.push_back(make_pair(a,1)); for(vi=v.begin();vi!=v.end();++vi) cout<<vi->first<<" "<<vi->second<<endl; }
Pollard算法
无论如何,我们都需要记住,这门科学是RP科学。因此,随机化算法一定是一个不可或缺的部分!不过虽然这么说……我觉得NOIP大概用不到这玩意吧,反正我是完全没有看懂……如果想搞懂的话可以参考
http://www.cnblogs.com/jackiesteed/articles/2019910.html
http://qkxue.net/info/120352/Pollard-rho
相关文章推荐
- 数论基础题目八题【欧几里得】【筛法素数】【中国剩余定理】
- 基础数论算法(5) 素数的判定
- 数论之素数(质因数分解与筛法)
- Java编程算法基础---素数与筛法
- 【数论】【素数】素数相关基础——整数分解
- ACM数论基础之一_______质因数分解
- Miller_Rabin 算法进行素数测试 pollard_rho 算法进行质因数分解 poj1811Prim Test
- 算法:素数的筛法
- 算法基础 - 素数判定(Miller-Rabin算法)
- 基础数论算法(⑩) Catalan数与Stirling数
- 基础素数算法
- 数论内容;各种模运算;筛法打素数表;
- 基础数论算法(4) 中国剩余定理
- 对 质数筛法 和 质因数分解 的模版实验 - 数论
- 基础数论算法(三) 逆元和gcd的几道题
- 【数论基础算法合集】
- 基础数论算法(八) 矩阵乘法与线性齐次递推公式的快速求值
- 组合数的素数算法(ACM基础教程1010)
- 数论快速入门(同余、扩展欧几里德、中国剩余定理、大素数测定和整数分解、素数三种筛法、欧拉函数以及各种模板)
- 有关素数的基础算法--总结