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=b;i;i>>=1,a=mul(a,a,p))
10         if(i&1)ans=mul(ans,a,p);
11     return ans;
12 }
13 bool check(int a,int n,int r,int s){
14     int ans=pow(a,r,n),p=ans;
15     for(int i=1;i<=s;i++){
16         ans=mul(ans,ans,n);
17         if(ans==1&&p!=1&&p!=n-1) return true;
18         p=ans;
19     } if(ans!=1)return true;return false;
20 }
21 bool MR(int n){
22     if(n<=1) return false;
23     if(n==2) return true;
24     if(!(n&1)) return false;
25     int r=n-1,s=0;
26     while(!(r&1)) r>>=1,s++;
27     for(int i=0;i<Safe;i++)
28         if(check(rand()%(n-1)+1,n,r,s)) return false;
29     return true;
30 }

我是rho:

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <algorithm>
 4 #include <cstring>
 5 #include <cmath>
 6 #define ll long long
 7 #define inf 1000000000
 8 #define Safe 5
 9 using namespace std;
10 ll gcd(ll a, ll b){
11     return b == 0 ? a : gcd(b, a % b);
12 }
13 ll n, x, mx;
14 ll mul(ll a, ll b, ll p){
15     ll tmp = (a * b - (ll)((long double)a / p * b + 1e-8) * p);
16     return tmp < 0 ? tmp + p : tmp;
17 }
18 ll pow(ll a, ll b, ll p){
19     ll ans = 1; a %= p;
20     for(ll i = b; i; i >>= 1, a = mul(a, a, p))
21         if(i & 1) ans = mul(ans, a, p);
22     return ans;
23 }
24 bool check(ll a, ll n, ll r, ll s){
25     ll ans = pow(a, r, n), p = ans;
26     for(int i = 1; i <= s; i ++){
27         ans = mul(ans, ans, n);
28         if(ans == 1 && p != 1 && p != n - 1) return true;
29         p = ans;
30     }
31     if(ans != 1)return true;
32     return false;
33 }
34 bool MR(ll n){
35     if(n <= 1) return false;
36     if(n == 2) return true;
37     if(n % 2 == 0) return false;
38     ll r = n - 1, s = 0;
39     while(r % 2 == 0) r /= 2, s ++;
40     for(int i = 0; i < Safe; i ++)
41         if(check(rand() % (n - 1) + 1, n, r, s)) return false;
42     return true;
43 }
44 ll rho(ll n, ll c){
45     ll k = 2, x = rand() % n, y = x, p = 1;
46     for(ll i = 1; p == 1; i ++){
47         x = (mul(x, x, n) + c) % n;
48         p = y > x ? y - x : x - y;
49         p=gcd(n, p);
50         if(i == k) y = x, k += k;
51     }
52     return p;
53 }
54 void solve(ll n){
55     if(n == 1) return;
56     if(MR(n)) { mx = max(n, mx); return; }
57     ll t = n;
58     while(t == n) t = rho(n, rand() % (n - 1) + 1);
59     solve(t); solve(n / t);
60 }
61 void read(ll &x){
62     x = 0; ll sig = 1; char ch = getchar();
63     while(!isdigit(ch)) { if(ch == ‘-‘) sig = -1; ch = getchar(); }
64     while(isdigit(ch)) x = 10 * x + ch - ‘0‘, ch = getchar();
65     x *= sig; return ;
66 }
67 ll cnt = 0;
68 void init(){
69     read(n);
70     cnt = 0;
71     return ;
72 }
73 void work(){
74     while(n --){
75         read(x);
76         if(MR(x)) cnt ++;
77         mx = 0; solve(x);
78         if(mx == x) puts("Prime");
79         else printf("%lld\n", mx);
80     }
81     return ;
82 }
83 void print(){
84     printf("%lld\n", cnt);
85     return ;
86 }
87 int main(){
88     init();
89     work();
90     print();
91     return 0;
92 }
时间: 2024-10-07 02:35:47

Miller_Rabin素数判断,rho的相关文章

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 type

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