poj1811 Prime Test,随机素数测试

Prime Test

Time Limit: 6000MS   Memory Limit: 65536K
Total Submissions: 24514   Accepted: 5730
Case Time Limit: 4000MS

Description

Given a big integer number, you are required to find out whether it‘s a prime number.

Input

The first line contains the number of test cases T (1 <= T <= 20 ), then the following T lines each contains an integer number N (2 <= N < 254).

Output

For each test case, if N is a prime number, output a line containing the word "Prime", otherwise, output a line containing the smallest prime factor of N.

Sample Input

2
5
10

Sample Output

Prime
2

Miller_Rabin 算法

#include <cstdio>
#include <cstring>
#include <cmath>
#include <ctime>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;

// rand(void)返回一个[0,RAND_MAX]之间的随机整数。
//random(n) 返回一个[0,n]之间的随机整数
ll random(ll n) {
    return (ll)((double)rand()/RAND_MAX*n + 0.5);
}

inline ll mul_mod(ll a, ll b, ll c) {
    ll res = 0;
    a %= c;
    b %= c;
    for(; b; b>>= 1, a=(a<<1)%c) {
        if(b&1) res = (res+a)%c;
    }
    return res;
}

ll pow_mod(ll a, ll b, ll c) {
    ll res = 1;
    for(; b; b>>=1, a=mul_mod(a,a,c)) {
        if(b&1) res = mul_mod(res, a, c);
    }
    return res;
}

bool check(ll a, ll n, ll x, ll t) {
    ll ret = pow_mod(a, x, n);
    ll last = ret;
    for(int i=1; i<=t; ++i) {
        ret = mul_mod(ret, ret, n);
        if(ret==1 && last!=1 && last!=n-1) return true;
        last = ret;
    }
    if(ret!=1) return true;
    else return false;
}

const int N = 8;
bool miller_rabin(ll n) {
    if(n<2) return false;
    if(n==2) return true;
    if( (n&1)==0) return false;
    ll x = n-1;
    ll t = 0;
    while( (x&1)==0 ) {
        x >>= 1;
        t++;
    }

    for(int i=0; i< N; ++i) {
        ll a = random(x-2) + 1;
        if( check(a,n,x,t) )
            return false;
    }
    return true;
}

ll factor[100];
int tol;

ll gcd(ll a, ll b) {
        return b?gcd(b,a%b): a>=0?a:-a;
}

ll pollard_rho(ll x, ll c) {
    ll i=1, k=2;
    ll x0 = random(x-2) + 1;
    ll y = x0;
    while(1) {
        i++;
        x0 = (mul_mod(x0,x0,x) + c) % x;
        ll d = gcd(y-x0, x);
        if(d != 1 && d != x) return d;
        if(y == x0) return x;
        if(i == k) {
            y = x0;
            k += k;
        }
    }
}

void findfac(ll n, int k) {
    if(n==1) return ;
    if(miller_rabin(n)) {
        factor[tol++] = n;
        return ;
    }
    ll p = n;
    int c = k;
    while(p >= n) p = pollard_rho(p, c--);
    findfac(p, k);
    findfac(n/p, k);
}

int main() {
    int T;
    ll n;
   // srand(time(NULL));
   //POJ上G++要去掉这句话,一个忧伤的故事。。
    scanf("%d", &T);
    while(T--) {
        scanf("%lld", &n);
        if(miller_rabin(n)) {
            printf("Prime\n");
        } else {
            tol = 0;
            findfac(n, 107);
            ll ans = factor[0];
            for(int i=1; i<tol; ++i)
                if(ans > factor[i])
                        ans = factor[i];
            printf("%lld\n", ans);
        }
    }
    return 0;
}

时间: 2024-12-31 03:49:42

poj1811 Prime Test,随机素数测试的相关文章

随机素数测试(Miller_Rabin算法)和求整数素因子(Pollard_rho算法)

POJ1811 给一个大数,判断是否是素数,如果不是素数,打印出它的最小质因数 随机素数测试(Miller_Rabin算法) 求整数素因子(Pollard_rho算法) 科技题 1 #include<cstdlib> 2 #include<cstdio> 3 const int maxn=10005; 4 const int S=20; 5 int tot; 6 long long n; 7 long long factor[maxn]; 8 long long muti_mod(

HDU2138 随机素数测试 Miller-Rabin算法

题目描述 Give you a lot of positive integers, just to find out how many prime numbers there are.. In each case, there is an integer N representing the number of integers to find. Each integer won’t exceed 32-bit signed integer, and each of them won’t be

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

POJ1811 Prime Test(判断随机素数)

题意:给出一个N(2 <= N < 2^54),如果是素数,输出"Prime",否则输出最小的素因子 膜拜斌巨 #include <iostream> #include <cstdio> #include <cstring> #include <string> #include <queue> #include <cmath> #include <stdlib.h> #include <

数论 - Miller_Rabin素数测试 + pollard_rho算法分解质因数 ---- poj 1811 : Prime Test

Prime Test Time Limit: 6000MS   Memory Limit: 65536K Total Submissions: 29046   Accepted: 7342 Case Time Limit: 4000MS Description Given a big integer number, you are required to find out whether it's a prime number. Input The first line contains the

HDu 2138 How many prime numbers 高效Miller素数测试

题目就是给出一组数,让我们测试其中有多少个是素数. 求素数有测试sqrt(n)个数的方法,有筛子方法,不过对于本题这样的题目来说就都不是高效的. 本题使用Miller Rabin素数测试法,效率奇高,对于不是极其大的整数测试都几乎是常数时间.令人神往的算法啊. 网上有个程序,好像是什么吉林的模板程序,不过我一直没看懂他是什么思路写的,是个AC的程序,不过却是错误的,呵呵,因为程序一直把9当做素数. 于是上网查找了其中原理,自己写了个程序,效率和他的差不多一样,通过时间基本无差别,不过我的思路是按

Miiler-Robin素数测试与Pollard-Rho大数分解法

板题 Miiler-Robin素数测试 目前已知分解质因数以及检测质数确定性方法就只能\(sqrt{n}\)试除 但是我们可以基于大量测试的随机算法而有大把握说明一个数是质数 Miler-Robin素数测试基于以下两个原理: 费马小定理 即我们耳熟能详的 对于质数\(p\) \[a^{p - 1} \equiv 1 \pmod p\] 二次探测原理 对于质数\(p\),如果存在\(x\)满足 \[x^2 \equiv 1 \pmod p\] 那么\(x\)只能是\(1\)或者\(p - 1\)

POJ 1811Prime Test(米勒拉宾素数测试)

直接套用模板,以后接着用 这里还有一个素因子分解的模板 1 #include <map> 2 #include <set> 3 #include <stack> 4 #include <queue> 5 #include <cmath> 6 #include <ctime> 7 #include <vector> 8 #include <cstdio> 9 #include <cctype> 10

csu 1552(米勒拉宾素数测试+二分图匹配)

1552: Friends Time Limit: 3 Sec  Memory Limit: 256 MBSubmit: 723  Solved: 198[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 extraterrestr