51nod1186(Miller-Rabin)
题目链接: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)的更多相关文章
- 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 这 ...
- POJ1811- Prime Test(Miller–Rabin+Pollard's rho)
题目大意 给你一个非常大的整数,判断它是不是素数,如果不是则输出它的最小的因子 题解 看了一整天<初等数论及其应用>相关部分,终于把Miller–Rabin和Pollard's rho这两 ...
- poj 1811 Pallor Rho +Miller Rabin
/* 题目:给出一个数 如果是prime 输出prime 否则输出他的最小质因子 Miller Rabin +Poller Rho 大素数判定+大数找质因子 后面这个算法嘛 基于Birthday Pa ...
- POJ1811_Prime Test【Miller Rabin素数测试】【Pollar Rho整数分解】
Prime Test Time Limit: 6000MS Memory Limit: 65536K Total Submissions: 29193 Accepted: 7392 Case Time ...
- Miller Rabin算法详解
何为Miller Rabin算法 首先看一下度娘的解释(如果你懒得读直接跳过就可以反正也没啥乱用:joy:) Miller-Rabin算法是目前主流的基于概率的素数测试算法,在构建密码安全体系中占有重 ...
- 与数论的厮守01:素数的测试——Miller Rabin
看一个数是否为质数,我们通常会用那个O(√N)的算法来做,那个算法叫试除法.然而当这个数非常大的时候,这个高增长率的时间复杂度就不够这个数跑了. 为了解决这个问题,我们先来看看费马小定理:若n为素数, ...
- $Miller Rabin$总结
\(Miller Rabin\)总结: 这是一个很高效的判断质数的方法,可以在用\(O(logn)\) 的复杂度快速判断一个数是否是质数.它运用了费马小定理和二次探测定理这两个筛质数效率极高的方法. ...
- 关于素数:求不超过n的素数,素数的判定(Miller Rabin 测试)
关于素数的基本介绍请参考百度百科here和维基百科here的介绍 首先介绍几条关于素数的基本定理: 定理1:如果n不是素数,则n至少有一个( 1, sqrt(n) ]范围内的的因子 定理2:如果n不是 ...
- POJ2429_GCD & LCM Inverse【Miller Rabin素数測试】【Pollar Rho整数分解】
GCD & LCM Inverse Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 9756Accepted: 1819 ...
- Pollard rho算法+Miller Rabin算法 BZOJ 3668 Rabin-Miller算法
BZOJ 3667: Rabin-Miller算法 Time Limit: 60 Sec Memory Limit: 512 MBSubmit: 1044 Solved: 322[Submit][ ...
随机推荐
- apache 绿色版 安装
下载绿色版apache 本文已apache2.4为例 http://www.apachehaus.com/cgi-bin/download.plx 下载后解压 打开readme_first.html文 ...
- angularJs-HelloWorld
AngularJS使用了不同的方法,它尝试去补足HTML本身在构建应用方面的缺陷.AngularJS通过使用我们称为标识符(directives)的结构,让浏览器能够识别新的语法. 1使用双大括号{{ ...
- HDU - 4990 Reading comprehension 【矩阵快速幂】
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=4990 题意 初始的ans = 0 给出 n, m for i in 1 -> n 如果 i 为奇 ...
- webpack-dev-server原理及要点笔记
webpack-dev-server启动了一个使用express的Http服务器,这个服务器与客户端采用websocket通信协议,当原始文件发生改变,webpack-dev-server会实时编译. ...
- Matlab的publish功能和cell功能
Matlab的publish功能能够让写的代码变成优美的文档.类似为知笔记的markdown语言. cell功能配合publish使用,可以形成不同的功能块.而且调试的时候,可以按section调试. ...
- 使用gdb调试c/c++代码
转自 http://blog.csdn.net/haoel/article/details/2879 GDB概述———— GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具.或许,各位比较 ...
- PHP按照比例随机
有这样的需求,在打开链接的时候,随机(按照项目的某个属性的比例随机)跳转到指定的几个项目的某一个项目页面 比如项目A:80 项目B:20 那么跳转到项目A 的比例为80%,项目B的比例为20% 那么 ...
- Java IO(输入输出)
1. System.out.System.in System 内部: public final static InputStream in = null; public final static Pr ...
- 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 ...
- uC/OS-II源码分析(五)
每个任务被赋予不同的优先级等级,从0 级到最低优先级OS_LOWEST_PR1O,包括0 和 OS_LOWEST_PR1O 在内.当μC/OS-Ⅱ初始化的时候,最低优先级OS_LOWEST_PR1O ...