POJ1811-Prime Test-素数测试+Pollard rho因数分解
来源:互联网 发布:足彩分析软件 编辑:程序博客网 时间:2024/05/02 02:17
题意:
给你一个数n(n <= 2^54),判断n是不是素数,如果是输出Prime,否则输出n最小的素因子
参考:先用miller_rubin素数测试判断是否为素数,是则用Pollard rho因数分解得到最小素因子
以下代码是网上找的,前面的稳定在1S+,后面的1/3概率TLE,但是run time 稳定在500S
稳定1S+代码:
#include <cstdio>#include <cstdlib>#include <ctime>typedef __int64 LL;int T;LL n, s;LL factor[110000];LL mods(LL x, LL y, LL n){x %= n;y %= n;LL tmp = 0;while(y){if(y & 1)tmp = (tmp + x) % n;x = (x << 1) % n;y >>= 1;}return tmp;}LL pow(LL x, LL y, LL n){x %= n;LL tmp = 1;while(y){if(y&1) tmp = mods(tmp, x, n);x = mods(x, x, n);y >>= 1;}return tmp;}int judge(LL tmp, LL n, LL m, LL t){//n - 1 == m * 2^ tLL tp = m;LL v = pow(tmp , m, n);LL last = v;for(LL i = 1; i <= t; i++){v = mods(v, v, n);if(v == 1){if(last != 1 && last != n-1)return 0;}last = v;tp <<= 1;}if(v == 1)return 1;return 0;}int miller_rubin(LL x, int k){LL cnt = 0;LL m = x - 1;while(!(m & 1)) cnt++, m >>= 1;while(k--){LL tmp = rand()%(x-1) + 1;if(!judge(tmp, x, m, cnt)){return 0;}}return 1;}LL gcd(LL a, LL b){return b == 0?a: gcd(b, a%b);}LL f(LL x, LL n, LL c){return (mods(x, x, n) + c) % n;}LL poll(LL n, LL c){if(!(n & 1))return 2;LL x = rand() % n;LL y = x;LL i = 1;LL k = 2;while(1){i++;x = f(x, n, c);LL d = gcd(y - x + n, n);if(d != 1 && d != n)return d;if(y == x)return n;if(i == k){y = x;k += k;}}}void find(LL n){if(miller_rubin(n,5)){factor[s++] = n;return;}LL p = n;while(p >= n) p = poll(p, (LL)(rand()%(n-1)+1));find(p);find(n/p);}int main(){srand(time(NULL));scanf("%d",&T);while(T--){scanf("%I64d",&n);if(n == 1)break;s = 0;find(n);if(s == 1){printf("Prime\n");continue;}LL tp = 10000000000LL;for(int i = 0; i < s; i++){if(tp > factor[i])tp = factor[i];}printf("%I64d\n",tp);}return 0;}
大几率TLE,但是ac time 500ms+
//此代码提交有1/3几率TLE,但是AC时间稳定在500S-#include<iostream>#include<ctime>#include<cstdlib>#include<cmath>#include<algorithm>#define MAX (pow(2.0, 60)) //标记最大值#define C 240#define TIME 12 //Miller测试次数using namespace std;__int64 MIN;__int64 gcd(__int64 a, __int64 b) //计算a和b的最大公约数 { if (b == 0) return a; return gcd(b, a % b);}__int64 mod_mult(__int64 a, __int64 b, __int64 n) //计算(a*b) mod n{ __int64 s = 0; a = a % n; while (b) { if (b & 1) { s += a; if (s >= n) s -= n; } a = a << 1; if (a >= n) a -= n; b = b >> 1; } return s;}__int64 mod_exp(__int64 a, __int64 b, __int64 n) //计算(a^b) mod n{ __int64 d = 1; a = a % n; while (b >= 1) { if (b & 1) d = mod_mult(d, a, n); a = mod_mult(a, a, n); b = b >> 1; } return d;}bool Wintess(__int64 a, __int64 n) //以a为基对n进行Miller测试并实现二次探测{ __int64 m, x, y; int i, j = 0; m = n - 1; while (m % 2 == 0) //计算(n-1)=m*(2^j)中的j和m,j=0时m=n-1,不断的除以2直至n为奇数 { m = m >> 1; j++; } x = mod_exp(a, m, n); for (i = 1; i <= j; i++) { y = mod_exp(x, 2, n); if ((y == 1) && (x != 1) && (x != n - 1)) //二次探测 return true; //返回true时,n是合数 x = y; } if (y != 1) return true; return false;}bool miller_rabin(int times, __int64 n) //对n进行s次的Miller测试{ __int64 a; int i; if (n == 1) return false; if (n == 2) return true; if (n % 2 == 0) return false; srand(time(NULL)); for (i = 1; i <= times; i++) { a = rand() % (n - 1) + 1; if (Wintess(a, n)) return false; } return true;}__int64 Pollard(__int64 n, int c) //对n进行因字分解,找出n的一个因子,注意该因子不一定是最小的{ __int64 i, k, x, y, d; srand(time(NULL)); i = 1; k = 2; x = rand() % n; y = x; while (true) { i++; x = (mod_mult(x, x, n) + c) % n; d = gcd(y - x, n); if (d > 1 && d < n) return d; if (y == x) //该数已经出现过,直接返回即可 return n; if (i == k) { y = x; k = k << 1; } }}void get_small(__int64 n, int c) //找出最小的素数因子{ __int64 m; if (n == 1) return; if (miller_rabin(TIME, n)) //判断是否为素数 { if (n < MIN) MIN = n; return; } m = n; while (m == n) //找出n的一个因子 m = Pollard(n, c--); get_small(m, c); //二分查找 get_small(n / m, c);}int main() { int total; __int64 n; scanf("%d", &total); while (total--) { scanf("%I64d", &n); MIN = MAX; if (miller_rabin(TIME, n)) printf("Prime\n"); else { get_small(n, C); printf("%I64d\n", MIN); } } return 0;}
0 0
- POJ1811-Prime Test-素数测试+Pollard rho因数分解
- POJ1811 (Prime Test Pollard rho整数分解,Miller-Rabin素数测试)
- 【POJ1811】Prime Test-Miller-Rabin素数测试+Pollard-rho大数分解
- POJ1811 miller-rabin素数测试pollard-rho质因子分解
- POJ1811 Prime Test (Pollard-Rho算法)
- POJ 1811 Prime Test(Pollard rho整数分解+miller_rabin素数测试)
- Poj 1811 Prime Test 素数测试 Miller-Rabin 与 整数的因子分解 Pollard rho
- Pollard Rho因数分解
- poj1811(Miller-Rabin(素数测试)与Pollard rho(整数的因子分解))
- POJ1811 Prime Test (Pollard-Rho算法) Sunshine大神
- 大数因数分解pollard rho
- poj1811 Prime Test 素数测试 +整数分解+分治
- POJ1811 Prime Test miller_rabin素数测试+pollard_rho整数分解
- POJ 1811 Prime Test(素数判定Miller-Rabin+素因子分解Pollard-rho)
- 【快速因数分解】Pollard's Rho 算法
- [快速因数分解]Pollard's Rho 算法
- poj1811 Prime Test,随机素数测试
- Miller-Rabin素数测试和Pollard-rho大整数分解
- Ubuntu下添加开机启动脚本
- ubuntu proxy setting
- asp.net三层架构详解
- 盘点大佬们的第一份工作,你和雷军差了 16 年的坚持!
- 指针的用法
- POJ1811-Prime Test-素数测试+Pollard rho因数分解
- Spritekit游戏开发之SKSpriteNode(精灵)一
- UVA 11582 Colossal Fibonacci Numbers!(模运算)
- FreeBSD设置IP地址、网关、DNS的方法
- static的用法
- iOS中 超简单抽屉效果(MMDrawerController)的实现
- .NET完全手动搭建三层B/S架构
- UVA 12169 Disgruntled Judge(暴力)
- 不为繁华易匠心