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][ ...
随机推荐
- java基础语言 运算符
/* ++,--运算符的使用: 单独使用: 放在操作数的前面和后面效果一样.(这种用法是我们比较常见的) 参与运算使用: 放在操作数的前面,先自增或者自减,然后再参与运算. 放在操作数的后面,先参与运 ...
- Flask中的内置session
Flask中的Session非常的奇怪,他会将你的SessionID存放在客户端的Cookie中,使用起来也非常的奇怪 1. Flask 中 session 是需要 secret_key 的 from ...
- iOS define 宏定义 和 const定义常量区别
const const 是c++中的修饰符. c++中常用来定义常量,修饰左值. #define 宏定义语句, 在预处理阶段直接做文本替换,不做类型检查. 它们之间的最大区别: 1. 对于co ...
- uboot 2013.01 代码简析(2)第一阶段初始化
uboot执行"make smdk2410_config"之后就可以进行编译了,可以执行make命令进行编译, 因为整个输出太长,我仅仅列出部分最关键的输出(部分我不关心的内容直接 ...
- C++中输出 位宽和小数点后位数 的控制
要用到这个头文件: <iomanip> setw(x) : 表示控制输出x的位宽 setprecision(x) :表示 控制输出小数点后 x 位 cout.precision(x): 表 ...
- LibreOJ 数列分块入门
题目链接:https://loj.ac/problem/6277 题目描述 给出一个长为 nnn 的数列,以及 nnn 个操作,操作涉及区间加法,单点查值. 输入格式 第一行输入一个数字 nnn. 第 ...
- 作业:xml练习1
作业:使用xml描述下表中的学生成绩信息,XML文件存为scores.xml. 1.打开eclipse软件. 2.file-new-java project,输入project name:201811 ...
- 【详解】苹果AppStore审核被拒,原因终逃不过这些!
近日,相信很多开发者都留意到了: 苹果针对应用标题的审核确有明显的变严趋势!我们在<惊!苹果再次加强审核力度,众App纷纷止步应用标题>中也对该现象进行了详细的分析,并给出了相应的解决方案 ...
- 微信video和audio无法自动播放解决方案
//音频,写法一<audio src="music/bg.mp3" autoplay loop controls>你的浏览器还不支持哦</audio> // ...
- Java并发模型(一)
学习资料来自http://ifeve.com/java-concurrency-thread-directory/ 一.多线程 进程和线程的区别: 一个程序运行至少一个进程,一个进程至少包含一个线程. ...