题目链接: http://poj.org/problem?id=1811

题意: 判断一个数 n (2 <= n < 2^54)是否为质数, 是的话输出 "Prime", 否则输出其第一个质因子.

思路: 大数质因子分解, 直接用 pollard_rho (详情参见: http://blog.csdn.net/maxichu/article/details/45459533) 模板即可.

代码:

 #include <iostream>
#include <algorithm>
#define ll long long
using namespace std; const int MAXN = 1e2;
const int repeat = ;//repeat为检测次数,判断错误率为4^-repeat,一般8~10就够了 ll get_mult(ll a, ll b, ll c){//返回a*b%c
a %= c;
b %= c;
ll ret = ;
while(b){
if(b & ){
ret += a;
if(ret >= c) ret -= c;
}
b >>= ;
a <<= ;
if(a >= c) a -= c;
}
return ret;
} ll get_pow(ll x, ll n, ll mod){//返回x^n%mod
ll ret = ;
x %= mod;
while(n){
if(n & ) ret = get_mult(ret, x, mod);
x = get_mult(x, x, mod);
n >>= ;
}
return ret;
} //通过 a^(n-1) = 1(mod n) 来判断n是否为素数
//n-1 = x*2^t 中间使用二次探测定理
//是合数返回true,不一定是合数返回false
bool cherk(ll a, ll n, ll x, ll t){
ll ret = get_pow(a, x, n);
ll last = ret;
for(int i = ; i <= t; i++){
ret = get_mult(ret, ret, n);
if(ret == && last != && last != n - ) return true;
last = ret;
}
if(ret != ) return true;
return false;
} bool Miller_Rabin(ll n){
if(n < ) return false;
if(n == ) return true;
if(!(n & )) return false;//偶数
ll x = n - , t = ;
while(!(x & )){
x >>= ;
t++;
}
// srand(time(NULL));
for(int i = ; i < repeat; i++){
ll a = rand() % (n - ) + ;
if(cherk(a, n, x, t)) return false;
}
return true;
} ll factor[MAXN];
int tot;//n的质因子个数 ll get_gcd(ll a, ll b){
ll tmp;
while(b){
tmp = a;
a = b;
b = tmp % b;
}
return a >= ? a : -a;
} ll pollard_rho(ll x, ll c){//返回x的一个因子
ll i = , k = ;
// srand(time(NULL));
ll x0 = rand() % (x - ) + ;
ll y = x0;
while(){
i++;
x0 = (get_mult(x0, x0, x) + c) % x;
ll d = get_gcd(y - x0, x);
if(d != && d != x) return d;
if(y == x0) return x;
if(i == k){
y = x0;
k += k;
}
}
} void findfac(ll n, int k){//对n质因分解并将结果保存到factor中
if(n == ) return;
if(Miller_Rabin(n)){
factor[tot++] = n;
return;
}
ll p = n;
int c = k;//c防止死循环
while(p >= n){
p = pollard_rho(p, c--);
}
findfac(p, k);
findfac(n / p, k);
} int main(void){
ll n;
int t;
cin >> t;
while(t--){
cin >> n;
if(Miller_Rabin(n)) cout << "Prime" << endl;
else{
tot = ;
findfac(n, );
ll sol = factor[];
for(int i = ; i < tot; i++){
sol = min(sol, factor[i]);
}
cout << sol << endl;
}
}
return ;
}

最新文章

  1. 自己写了一个无缝滚动的插件(jQuery)
  2. Linux常用命令及shell脚本
  3. Redhat Linux 修改主机名(HOSTNAME)
  4. JS 基础 入门
  5. 【python】入门学习(九)
  6. 【转】 HTTP 协议简介
  7. 【读书笔记】iOS-自动释放池
  8. 51 NOD 1685 第K大区间2 二分+BIT
  9. import static与import的区别
  10. iOSpush过后返回多级界面
  11. axis2调用webservice
  12. frameset iframe用来分页
  13. hp-ux-ia64:jffi/ffi 编译总结
  14. 基于JS的问卷调查
  15. 中国移动飞信WAP登陆分析及脚本
  16. spring使用之旅(一) ---- bean的装配
  17. HtmlWebpackPlugin用的html的ejs模板文件中如何使用条件判断
  18. No Spring WebApplicationInitializer types detected on classpath 问题的一种解决办法
  19. canvas-6font.html
  20. Feign 使用入门

热门文章

  1. 机器学习:评价分类结果(Precision - Recall 的平衡、P - R 曲线)
  2. 无法删除image报rbd: error: image still has watchers解决方法
  3. PowerDesigner中CDM和PDM如何定义外键关系
  4. 如何深度优化MySQL内核
  5. ThinkPad E431按F1后直接进入系统无法进入BIOS
  6. .net 4 安装未成功,无意中的解决办法!
  7. python爬虫实战(2)--爬取百度贴吧
  8. JAVA基础知识总结13(同步)
  9. C语言基础问题总结
  10. 【总结整理】arcgis js api的Map类