素性测试poj1811
来源:互联网 发布:中小学课本同步软件 编辑:程序博客网 时间:2024/06/16 06:03
分析:
经典题!!
数学题
miller_rabbin素数判定。若不是,则pollard_rho分解质因子,找到最小即可。
Miller-rabin
Miller-rabin算法是一个用来快速判断一个正整数是否为素数的算法。它利用了费马小定理,即:如果p是质数,且a,p互质,那么a^(p-1) mod p恒等于1。也就是对于所有小于p的正整数a来说都应该复合a^(p-1) mod p恒等于1。那么根据逆否命题,对于一个p,我们只要举出一个a(a<p)不符合这个恒等式,则可判定p不是素数。Miller-rabin算法就是多次用不同的a来尝试p是否为素数。
但是每次尝试过程中还做了一个优化操作,以提高用少量的a检测出p不是素数的概率。这个优化叫做二次探测。它是根据一个定理:如果p是一个素数,那么对于x(0<x<p),若x^2 mod p 等于1,则x=1或p-1。逆否命题:如果对于x(0<x<p),若x^2 mod p 不等于1,则p不是素数。根据这个定理,我们要计算a^(p-1) mod p是否等于1时,可以这样计算,设p-1=(2^t) * k。我们从a^k开始,不断将其平方直到得到a^(p-1),一旦发现某次平方后mod p等于1了,那么说明符合了二次探测定理的逆否命题使用条件,立即检查x是否等于1或p-1,如果不是则可直接判定p为合数。
pollard-rho
这是一个用来快速对整数进行质因数分解的算法,需要与Miller-rabin共同使用。求n的质因子的基本过程是,先判断n是否为素数,如果不是则按照一个伪随机数生成过程来生成随机数序列,对于每个生成的随机数判断与n是否互质,如果互质则尝试下一个随机数。如果不互质则将其公因子记作p,递归求解p和n/p的因子。如果n是素数则直接返回n为其素因子。
至于这个随机数序列是如何生成的暂时还不能理解,而且也是有多种不同的方式。这个序列生成过程中会产生循环,遇到循环则立即退出。
/* 题目形式:素性测试 题意:给定一个64位整数,问是否为质数, 如果不是,则输出其最小因子。 时间复杂度:难以估计*/typedef long long LL;const int S = 20; //进行素性测试的循环次数const int MAXN = 10000;LL factor[MAXN];int tot;LL muti_mod(LL a,LL b,LL c){ //返回(a*b) mod c [a,b,c < 2^63] a %= c; b %= c; LL ret = 0; while(b > 0){ if(b & 1){ ret += a; if(ret >= c) ret -=c; } a <<= 1; if(a >= c) a -= c; b >>= 1; } return ret;}LL pow_mod(LL x,LL n,LL mod){ //返回x^n mod c LL ret = 1; while(n > 0){ if(n&1) ret = muti_mod(ret,x,mod); x = muti_mod(x,x,mod); n >>= 1; } return ret;}//以a为基,n-1 = x*2^t,检验n是不是合数bool check(LL a,LL n,LL x,LL t){ LL ret = pow_mod(a,x,n),last = ret; for(int i = 1;i <= t;++i){ ret = muti_mod(ret,ret,n); if(ret == 1 && last != 1 && last != n -1) return true; last = ret; } if(ret != 1) return true; return false;}bool Miller_Rabin(LL n){ LL x = n - 1,t = 0; while((x&1) == 0){x >>= 1; ++t;} bool flag = true; if(t >= 1 && (x&1) == 1){ for(int k = 0;k < S;++k){ LL a = rand() % (n - 1) + 1; if(check(a,n,x,t)){flag = true;break;} flag = false; } } if(!flag || n == 2) return false; return true;}LL gcd(LL a,LL b){//a,b其一为0的时候要特判 //a,b为0最大公约数没有意义 if(a == 0) return b; if(a < 0) return gcd(-a,b); while(b > 0){ LL t = a % b; a = b; b = t; } return a;}LL Pollard_rho(LL x,LL c){ LL i = 1,x0 = rand() % x,y = x0,k = 2; while(1){ i++; x0 = (muti_mod(x0,x0,x) + c) % x; LL d = gcd(y - x0,x); if(d != 1&& d != x){ return d; } if(y == x0) return x; if(i == k){ y = x0; k += k; } }}void findfac(LL n){ //递归进行质因子数分解N if(!Miller_Rabin(n)){ factor[tot++] = n; return; } LL p = n;while(p >= n) p = Pollard_rho(p, rand() % (n - 1) + 1); findfac(p); findfac(n / p);}int main(){ int T; scanf("%d",&T); while(T--){ LL n; scanf("%I64d",&n); if(!Miller_Rabin(n)){ puts("Prime"); } else { tot = 0; findfac(n); LL ans = n; for(int i = 0;i < tot;++i) ans = min(ans,factor[i]); printf("%I64d\n",ans); } } return 0;}
- 素性测试poj1811
- 素性测试
- 素性测试
- 素性测试
- 素性测试
- Fermat素性测试, Miller-Rabin素性测试
- 素数与素性测试
- 大整数素性测试
- 素数与素性测试
- 随机化素性测试
- 素性测试算法
- POJ1811
- poj1811
- 大素数判断_fermat素性测试+Miller-Rabin素性测试
- 素数与素性测试【Matrix67】
- Miller–Rabin 素性测试
- Rabin-Miller素性测试算法
- Miller-Rabin大数素性测试
- sprintf函数详解
- [数据结构与算法]拓 扑 排 序
- 网站投资提示
- 蓝牙传输速率
- DBN和DNN的区别(未完待续)
- 素性测试poj1811
- 网站建设与制作基本的流程
- 网站建设规划书
- oracle 11g授权创建用户
- socket编程---之多连接服务端实现(CFNetwork框架)
- python 版DES和MAC算法
- Android音乐播放——MediaPlayer, unable to create media player
- John the Ripper使用方法概述
- 第二次