题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1186

题意:中文题目诶~

思路:miller_rabin模板 (详情可参见: http://blog.csdn.net/s031302306/article/details/51606018)

注意这里的 n 为 1e30,需要用字符串处理

代码:

 #include <string.h>
#include <cstdlib> #define MAXL 4
#define M10 1000000000
#define Z10 9 const int zero[MAXL - ] = {}; struct bnum{
int data[MAXL]; // 断成每截9个长度
// 读取字符串并转存
void read(){
memset(data, , sizeof(data));
char buf[];
scanf("%s", buf);
int len = (int)strlen(buf);
int i = , k;
while (len >= Z10){
for (k = len - Z10; k < len; ++k){
data[i] = data[i] * + buf[k] - '';
}
++i;
len -= Z10;
}
if (len > ){
for (k = ; k < len; ++k){
data[i] = data[i] * + buf[k] - '';
}
}
} bool operator == (const bnum &x){
return memcmp(data, x.data, sizeof(data)) == ;
} bnum & operator = (const int x){
memset(data, , sizeof(data));
data[] = x;
return *this;
} bnum operator + (const bnum &x){
int i, carry = ;
bnum ans;
for (i = ; i < MAXL; ++i){
ans.data[i] = data[i] + x.data[i] + carry;
carry = ans.data[i] / M10;
ans.data[i] %= M10;
}
return ans;
} bnum operator - (const bnum &x){
int i, carry = ;
bnum ans;
for (i = ; i < MAXL; ++i){
ans.data[i] = data[i] - x.data[i] - carry;
if (ans.data[i] < ){
ans.data[i] += M10;
carry = ;
}else{
carry = ;
}
}
return ans;
} // assume *this < x * 2
bnum operator % (const bnum &x){
int i;
for (i = MAXL - ; i >= ; --i){
if (data[i] < x.data[i]){
return *this;
}
else if (data[i] > x.data[i]){
break;
}
}
return ((*this) - x);
} bnum & div2(){
int i, carry = , tmp;
for (i = MAXL - ; i >= ; --i){
tmp = data[i] & ;
data[i] = (data[i] + carry) >> ;
carry = tmp * M10;
}
return *this;
} bool is_odd(){
return (data[] & ) == ;
} bool is_zero(){
for (int i = ; i < MAXL; ++i){
if (data[i]){
return false;
}
}
return true;
}
}; void mulmod(bnum &a0, bnum &b0, bnum &p, bnum &ans){//计算a0*b0%p
ans = ;
bnum tmp = a0, b = b0;
while (!b.is_zero()){
if (b.is_odd()){
ans = (ans + tmp) % p;
}
tmp = (tmp + tmp) % p;
b.div2();
}
} void powmod(bnum &a0, bnum &b0, bnum &p, bnum &ans){//计算a0^b0%p
bnum tmp = a0, b = b0;
ans = ;
while (!b.is_zero()){
if (b.is_odd()){
mulmod(ans, tmp, p, ans);
}
mulmod(tmp, tmp, p, tmp);
b.div2();
}
} bool MillerRabinTest(bnum &p, int iter){
int i, small = , j, d = ;
for (i = ; i < MAXL; ++i){
if (p.data[i]){
break;
}
}
if (i == MAXL){
// small integer test
if (p.data[] < ){
return false;
}
if (p.data[] == ){
return true;
}
small = ;
}
if (!p.is_odd()){
return false; // even number
}
bnum a, s, m, one, pd1;
one = ;
s = pd1 = p - one;
while (!s.is_odd()){
s.div2();
++d;
} for (i = ; i < iter; ++i){
a = rand();
if (small){
a.data[] = a.data[] % (p.data[] - ) + ;
}else{
a.data[] = a.data[] / M10;
a.data[] %= M10;
}
if (a == one){
continue;
} powmod(a, s, p, m); for (j = ; j < d && !(m == one) && !(m == pd1); ++j){
mulmod(m, m, p, m);
}
if (!(m == pd1) && j > ){
return false;
}
}
return true;
} int main(void){
bnum x;
x.read();
puts(MillerRabinTest(x, ) ? "Yes" : "No");
return ;
}

对于long long范围:

 #include <stdio.h>
#include <iostream>
#include <cstdlib>
#define ll long long
using namespace std; //利用二进制计算a*b%mod
ll multi_mod(ll a, ll b, ll mod){
ll ans = 0LL;
a %= mod;
while(b){
if (b & 1LL) ans = (ans+a)%mod;
b >>= 1LL;
a = (a+a)%mod;
}
return ans;
} //计算a^b%mod
ll power_mod(ll a, ll b, ll mod){
ll ans = 1LL;
a %= mod;
while(b){
if(b & 1LL) ans = multi_mod(ans, a, mod);
b >>= 1LL;
a = multi_mod(a, a, mod);
}
return ans;
} //Miller-Rabin测试,测试n是否为素数
bool miller_rabin(ll n, int repeat){
if (2LL == n || 3LL == n) return true;
if (n%== || n%== || n%==) return false; //将n分解为2^s*d
ll d = n - 1LL;
int s = ;
while(!(d & 1LL)){
s++;
d >>= 1LL;
}
// srand((unsigned)time(0));
for(int i=; i<repeat; ++i){//重复repeat次
ll a = rand() % (n - ) + ;//取一个随机数,[2,n-1)
ll x = power_mod(a, d, n);
ll y = 0LL;
for(int j=; j<s; ++j){
y = multi_mod(x, x, n);
if (1LL == y && 1LL != x && n-1LL != x) return false;
x = y;
}
if (1LL != y) return false;
}
return true;
} int main(void){
ll n;
cin >> n;
if(miller_rabin(n, )) cout << "Yes" << endl;
else cout << "No" << endl;
return ;
}

51nod1186(Miller-Rabin)的更多相关文章

  1. POJ2429 - GCD & LCM Inverse(Miller–Rabin+Pollard's rho)

    题目大意 给定两个数a,b的GCD和LCM,要求你求出a+b最小的a,b 题解 GCD(a,b)=G GCD(a/G,b/G)=1 LCM(a/G,b/G)=a/G*b/G=a*b/G^2=L/G 这 ...

  2. POJ1811- Prime Test(Miller–Rabin+Pollard's rho)

    题目大意 给你一个非常大的整数,判断它是不是素数,如果不是则输出它的最小的因子 题解 看了一整天<初等数论及其应用>相关部分,终于把Miller–Rabin和Pollard's rho这两 ...

  3. poj 1811 Pallor Rho +Miller Rabin

    /* 题目:给出一个数 如果是prime 输出prime 否则输出他的最小质因子 Miller Rabin +Poller Rho 大素数判定+大数找质因子 后面这个算法嘛 基于Birthday Pa ...

  4. POJ1811_Prime Test【Miller Rabin素数测试】【Pollar Rho整数分解】

    Prime Test Time Limit: 6000MS Memory Limit: 65536K Total Submissions: 29193 Accepted: 7392 Case Time ...

  5. Miller Rabin算法详解

    何为Miller Rabin算法 首先看一下度娘的解释(如果你懒得读直接跳过就可以反正也没啥乱用:joy:) Miller-Rabin算法是目前主流的基于概率的素数测试算法,在构建密码安全体系中占有重 ...

  6. 与数论的厮守01:素数的测试——Miller Rabin

    看一个数是否为质数,我们通常会用那个O(√N)的算法来做,那个算法叫试除法.然而当这个数非常大的时候,这个高增长率的时间复杂度就不够这个数跑了. 为了解决这个问题,我们先来看看费马小定理:若n为素数, ...

  7. $Miller Rabin$总结

    \(Miller Rabin\)总结: 这是一个很高效的判断质数的方法,可以在用\(O(logn)\) 的复杂度快速判断一个数是否是质数.它运用了费马小定理和二次探测定理这两个筛质数效率极高的方法. ...

  8. 关于素数:求不超过n的素数,素数的判定(Miller Rabin 测试)

    关于素数的基本介绍请参考百度百科here和维基百科here的介绍 首先介绍几条关于素数的基本定理: 定理1:如果n不是素数,则n至少有一个( 1, sqrt(n) ]范围内的的因子 定理2:如果n不是 ...

  9. POJ2429_GCD &amp; LCM Inverse【Miller Rabin素数測试】【Pollar Rho整数分解】

    GCD & LCM Inverse Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 9756Accepted: 1819 ...

  10. Pollard rho算法+Miller Rabin算法 BZOJ 3668 Rabin-Miller算法

    BZOJ 3667: Rabin-Miller算法 Time Limit: 60 Sec  Memory Limit: 512 MBSubmit: 1044  Solved: 322[Submit][ ...

随机推荐

  1. apache 绿色版 安装

    下载绿色版apache 本文已apache2.4为例 http://www.apachehaus.com/cgi-bin/download.plx 下载后解压 打开readme_first.html文 ...

  2. angularJs-HelloWorld

    AngularJS使用了不同的方法,它尝试去补足HTML本身在构建应用方面的缺陷.AngularJS通过使用我们称为标识符(directives)的结构,让浏览器能够识别新的语法. 1使用双大括号{{ ...

  3. HDU - 4990 Reading comprehension 【矩阵快速幂】

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=4990 题意 初始的ans = 0 给出 n, m for i in 1 -> n 如果 i 为奇 ...

  4. webpack-dev-server原理及要点笔记

    webpack-dev-server启动了一个使用express的Http服务器,这个服务器与客户端采用websocket通信协议,当原始文件发生改变,webpack-dev-server会实时编译. ...

  5. Matlab的publish功能和cell功能

    Matlab的publish功能能够让写的代码变成优美的文档.类似为知笔记的markdown语言. cell功能配合publish使用,可以形成不同的功能块.而且调试的时候,可以按section调试. ...

  6. 使用gdb调试c/c++代码

    转自 http://blog.csdn.net/haoel/article/details/2879 GDB概述———— GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具.或许,各位比较 ...

  7. PHP按照比例随机

    有这样的需求,在打开链接的时候,随机(按照项目的某个属性的比例随机)跳转到指定的几个项目的某一个项目页面 比如项目A:80  项目B:20 那么跳转到项目A 的比例为80%,项目B的比例为20% 那么 ...

  8. Java IO(输入输出)

    1. System.out.System.in System 内部: public final static InputStream in = null; public final static Pr ...

  9. CodeForces - 613D:Kingdom and its Cities(虚树+DP)

    Meanwhile, the kingdom of K is getting ready for the marriage of the King's daughter. However, in or ...

  10. uC/OS-II源码分析(五)

    每个任务被赋予不同的优先级等级,从0 级到最低优先级OS_LOWEST_PR1O,包括0 和 OS_LOWEST_PR1O 在内.当μC/OS-Ⅱ初始化的时候,最低优先级OS_LOWEST_PR1O  ...