[poj 1811]质数分解
2015-09-10 23:35
357 查看
题目链接,给定一个数,判断它是否是素数,如果是合数,就输出最小的质因子。
matrix67 大牛的文章,讲得很详细,好评!
Pallord−rhoPallord-rho 算法本质上是随机一个数 xx 判断 gcd(x,n)gcd(x,n) 是否是 nn 的一个约数
期望时间复杂度: O(n14∗logn)O(n^{\frac 1 4} * \log n)
Miller−rabinMiller-rabin 算法是通过费马小定理和二次探测来判断这个数是否是质数,可以处理强伪素数。
这个算法正确率为 1−(14)k1-(\frac 1 4)^k(kk 是选取的强伪证据的组数)。
时间复杂度: O(k∗logn)O(k*\log n)
注意一定要手写快速乘,不然会爆 long long。。。
matrix67 大牛的文章,讲得很详细,好评!
Pallord−rhoPallord-rho 算法本质上是随机一个数 xx 判断 gcd(x,n)gcd(x,n) 是否是 nn 的一个约数
期望时间复杂度: O(n14∗logn)O(n^{\frac 1 4} * \log n)
Miller−rabinMiller-rabin 算法是通过费马小定理和二次探测来判断这个数是否是质数,可以处理强伪素数。
这个算法正确率为 1−(14)k1-(\frac 1 4)^k(kk 是选取的强伪证据的组数)。
时间复杂度: O(k∗logn)O(k*\log n)
注意一定要手写快速乘,不然会爆 long long。。。
#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <ctime> #include <vector> #include <utility> #include <stack> #include <queue> #include <iostream> #include <algorithm> template<class Num>void read(Num &x) { char c; int flag = 1; while((c = getchar()) < '0' || c > '9') if(c == '-') flag *= -1; x = c - '0'; while((c = getchar()) >= '0' && c <= '9') x = (x<<3) + (x<<1) + (c-'0'); x *= flag; return; } template<class Num>void write(Num x) { if(x < 0) putchar('-'), x = -x; static char s[20];int sl = 0; while(x) s[sl++] = x%10 + '0',x /= 10; if(!sl) {putchar('0');return;} while(sl) putchar(s[--sl]); } const int Case = 3, prime[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 61, 24251}, tot = 16; const long long LINF = 1LL << 60; long long N, ans; long long Mult_Mod(long long a,long long k,long long p) { long long r = 0; a %= p; while(k) { if(k&1) r += a, r %= p; a <<= 1, a %= p, k >>= 1; } return r; } long long Power_Mod(long long a,long long k,long long p) { long long r = 1; a %= p; while(k) { if(k&1) r = Mult_Mod(r, a, p); a = Mult_Mod(a, a, p), k >>= 1; } return r; } long long gcd(long long a,long long b) { return b ? gcd(b, a % b) : a; } long long Pollard_Rho(long long n) { long long f = rand()%n, g = f, t; while(true) { for(int i = 0; i <= 1; i++) { g = (Mult_Mod(g, g, n) + 1) % n; t = gcd(llabs(g - f), n); if(t != 1 && t != n) return t; if(f == g) return n; } f = (Mult_Mod(f, f, n) + 1) % n; } } bool Miller_Rabin(long long n) { if(n == 2) return true; if(!(n&1)) return false; long long y = n - 1; int t = 0; while(!(y&1)) y >>= 1, t++; for (int i = 0; i < tot; i++) { if(n == prime[i]) return true; long long f = Power_Mod(prime[i], y, n), g = f; for(int j = 1; j <= t; j++) { f = Mult_Mod(f, f, n); if(f == 1 && g != 1 && g != n - 1) return false; g = f; } if(f != 1) return false; } return true; } void solve(long long n) { if(Miller_Rabin(n)) { ans = std::min(n, ans); return; } for(int i = 1; i <= Case; i++) { long long p = Pollard_Rho(n); if(p != n) { solve(p), solve(n/p); return; } } } int main() { int T; #ifndef ONLINE_JUDGE freopen("1811.in","r",stdin); freopen("1811.out","w",stdout); #endif srand(23333); read(T); while(T--) { read(N); ans = N; solve(N); if(ans < N) write(ans), puts(""); else puts("Prime"); } #ifndef ONLINE_JUDGE fclose(stdin); fclose(stdout); #endif return 0; }
相关文章推荐
- init进程【3】——属性服务
- 我的S5pv210裸机编程
- 犀牛——第10章 正则表达式的模式匹配 10.3
- 连载《一个程序猿的生命周期》- 29、解决基层员工提出的难题,也是无奈之事
- BlueTooth: 浅析CC2540的OSAL原理
- OS初识
- 【英语】Bingo口语笔记(75) - 元音辅音的辨读
- 4.windows环境下如何安装memcached教程(转载+自己整理)
- 4.windows环境下如何安装memcached教程(转载+自己整理)
- 面向对象(多态,抽象类,接口的比较)
- 快速理解类的访问控制(public,protected,private)
- MySQL基本用法
- 快速理解类的访问控制(public,protected,private)
- 连载《一个程序猿的生命周期》- 29、解决基层员工提出的难题,也是无奈之事
- VoLTE相关
- UC/OS II事件管理(3)之互斥信号量管理
- 第四篇:OC中的多态应用
- 《剑指offer》反转链表
- 黑马程序员——oc之Foundation框架
- NOIP2011 选择客栈