Miller_Rabin素数判断

说实话,我觉得反而慢了。不过前面两个函数的二进制写法还是很赞的。

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <algorithm>
 4 #include <cstring>
 5 #include <cmath>
 6 using namespace std;
 7 const int Save = 2;
 8 int N, cnt; bool Isprime = false;
 9 typedef unsigned long long LL;
10 LL S = 2;
11 LL modular_multi(LL x, LL y, LL mo){
12     LL t;
13     x %= mo;
14     for(t = 0; y; x = (x << 1) % mo, y >>= 1)
15         if (y & 1)
16             t = (t + x) % mo;
17     return t;
18 }
19 LL modular_exp(LL num, LL t, LL mo){
20     LL ret = 1, temp = num % mo;
21     for(;t;t >>= 1, temp = modular_multi(temp, temp, mo)) //56.58
22         if (t & 1)
23             ret = modular_multi(ret, temp, mo);
24     return ret;
25 }
26 bool miller_rabbin(LL n){
27     if (n == 2) return true;
28     if (n < 2 || !(n & 1)) return false;
29     int t = 0;
30     LL a, x, y, u = n-1;
31     while((u & 1) == 0) t ++,u >>= 1;
32     for(int i = 0; i < S; i ++){
33         a = rand() % (n - 1) + 1;
34         x = modular_exp(a, u, n);
35         for(int j = 0; j < t; j ++){
36             y = modular_multi(x, x, n);
37             if (y == 1 && x != 1 && x != n - 1)
38                 return false;
39             x = y;
40         }
41         if (x != 1)
42             return false;
43     }
44     return true;
45 }
46 void read(LL &x){
47     x = 0; int sig = 1; char ch = getchar();
48     while(!isdigit(ch)) { if(ch == ‘-‘) sig = -1; ch = getchar(); }
49     while(isdigit(ch)) x = 10 * x + ch - ‘0‘, ch = getchar();
50     x *= sig; return ;
51 }
52 bool init(){
53     cin >> N;
54     if(N == 0) return false;
55     cnt = 0;
56     return true;
57 }
58 void work(){
59     LL a;
60     while(N --){
61         read(a);
62         if(miller_rabbin(a)) cnt ++;
63     }
64     return ;
65 }
66 void print(){
67     printf("%d\n", cnt);
68     return ;
69 }
70 int main(){
71     while(init()){
72         work();
73         print();
74     }
75     return 0;
76 }
时间: 2024-10-25 01:43:53

Miller_Rabin素数判断的相关文章

Miller_Rabin素数判断,rho

safe保险一点5吧.我是MR: 1 const int Safe=3; 2 int gcd(int a,int b){return !b?a:gcd(b,a%b);} 3 int mul(int a,int b,int p){ 4 int tmp=(a*b-(int)((double)a/p*b+1e-8)*p); 5 return tmp<0?tmp+p:tmp; 6 } 7 int pow(int a,int b,int p){ 8 int ans=1;a%=p; 9 for(int i=

POJ 1811 大素数判断

数据范围很大,用米勒罗宾测试和Pollard_Rho法可以分解大数. 模板在代码中 O.O #include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> using namespace std; __int64 pri[]= {2,3,5,7,11,13,17,19,23,29,31};//用小素数表做随机种子避免第一类卡米

POJ1811 Prime Test(miller素数判断&amp;&amp;pollar_rho大数分解)

http://blog.csdn.net/shiyuankongbu/article/details/9202373 发现自己原来的那份模板是有问题的,而且竟然找不出是哪里的问题,所以就用了上面的链接上的一份代码,下面只是寄存一下这份代码,以后打印出来当模板好了. #pragma warning(disable:4996) #include <iostream> #include <cstring> #include <algorithm> #include <c

csu 1552: Friends(大素数判断+二分图)

1552: Friends Time Limit: 3 Sec  Memory Limit: 256 MB Submit: 525  Solved: 136 [Submit][Status][Web Board] Description On an alien planet, every extraterrestrial is born with a number. If the sum of two numbers is a prime number, then two extraterres

Miller_Rabin素数测试算法模板对比

昨天在USACO做了一道判断素数的题,就想着学习一下Miller_Rabin素数测试算法,在网上找到两种模版,第一种十分简洁,运行速度也很快,但是会判错极少的几个非素数:第二种比较麻烦,运行速度很慢,所以我便想找到第一种模版不能判断的非素数特判一下,结果用了一天,电脑只找到10^8以下的,10^9内还有2个没找到,但正确的模版运行速度太慢,我的电脑又太渣,耗不起时间了,姑且先这样,等以后有深入理解有更好的方法再更新一下. 第一种:源自吉林大学ACM模版 刚开始用的是随机数测试,我想到以前了解过只

有关素数判断的一些算法(总结&amp;&amp;对比)

素性测试是数论题中比较常用的一个技巧.它可以很基础,也可以很高级(哲学).这次主要要介绍一下有关素数判断的奇技淫巧 素数的判断主要分为两种:范围筛选型&&单个判断型 我们先从范围筛选型这种常用的开始讲起,这里采用模板题Luogu P3383 [模板]线性筛素数来进行测试 1.埃氏筛 这是最常用的筛法了,思路也很简单:任何一个素数的倍数都是合数 然后我们O(n)扫一遍,同时筛去素数的倍数 但是有一些数如6,会被2和3都筛去一次,就造成了效率上的浪费,所以复杂度经证明为**O(n log lo

筛素数方法(二)—— MR素数判断

前言 \(Miller-Rabin\)素数测试是一个很好的筛素数方法,它的优点在于速度快且准确性较高,但依然有可能出错. 大致思路 \(MR\)素数测试利用费马小定理快速判断一个数是否是素数,但是由于这种方法只是较高概率不出现错误,并不是完全正确的,所以在时间充裕的情况下可不必使用这个方法. 具体实现 因为当\(n\)是素数,且\(gcd(a,n)=1\)时,\(a^{n?1}\equiv1(mod\ n)\). 所以我们可以多随机几个\(a\)(用于增加算法的准确性),然后判断\(a^{n?1

POJ3641 Pseudoprime numbers(快速幂+素数判断)

POJ3641 Pseudoprime numbers p是Pseudoprime numbers的条件: p是合数,(p^a)%p=a;所以首先要进行素数判断,再快速幂. 此题是大白P122 Carmichael Number 的简化版 /* * Created: 2016年03月30日 22时32分15秒 星期三 * Author: Akrusher * */ #include <cstdio> #include <cstdlib> #include <cstring&g

POJ 2262 Goldbach&#39;s Conjecture (素数判断)

Goldbach's Conjecture Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 37693   Accepted: 14484 Description In 1742, Christian Goldbach, a German amateur mathematician, sent a letter to Leonhard Euler in which he made the following conject