POJ 1811 Prime Test(Miller-Rabin & Pollard-rho素数测试)

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.
 
题目大意:给一个数n,问是不是素数,若是输出Prime,若不是输出其最小的非1因子。
思路:http://www.2cto.com/kf/201310/249381.html
模板盗自:http://vfleaking.blog.163.com/blog/static/1748076342013231104455989/
 
代码(375MS):
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstring>
 5 #include <iterator>
 6 #include <vector>
 7 using namespace std;
 8 
 9 typedef long long LL;
10 
11 LL modplus(LL a, LL b, LL mod) {
12    LL res = a + b;
13    return res < mod ? res : res - mod;
14 }
15 
16 LL modminus(LL a, LL b, LL mod) {
17    LL res = a - b;
18    return res >= 0 ? res : res + mod;
19 }
20 
21 LL mult(LL x, LL p, LL mod) {
22     LL res = 0;
23     while(p) {
24         if(p & 1) res = modplus(res, x, mod);
25         x = modplus(x, x, mod);
26         p >>= 1;
27     }
28     return res;
29 }
30 
31 LL power(LL x, LL p, LL mod) {
32     LL res = 1;
33     while(p) {
34         if(p & 1) res = mult(res, x, mod);
35         x = mult(x, x, mod);
36         p >>= 1;
37     }
38     return res;
39 }
40 
41 bool witness(LL n, LL p) {
42    int t = __builtin_ctz(n - 1);
43    LL x = power(p % n, (n - 1) >> t, n), last;
44    while(t--) {
45        last = x, x = mult(x, x, n);
46        if(x == 1 && last != 1 && last != n - 1) return false;
47    }
48    return x == 1;
49 }
50 
51 const int prime_n = 5;
52 int prime[prime_n] = {2, 3, 7, 61, 24251};
53 
54 bool isPrime(LL n) {
55    if(n == 1) return false;
56    if(find(prime, prime + prime_n, n) != prime + prime_n) return true;
57    if(n % 2 == 0) return false;
58    for(int i = 0; i < prime_n; i++)
59        if(!witness(n, prime[i])) return false;
60    return true;
61 }
62 
63 LL getDivisor(LL n) {
64    int c = 1;
65    while (true) {
66        int i = 1, k = 2;
67        LL x1 = 1, x2 = 1;
68        while(true) {
69            x1 = modplus(mult(x1, x1, n), c, n);
70            LL d = __gcd(modminus(x1, x2, n), n);
71            if(d != 1 && d != n) return d;
72            if(x1 == x2) break;
73            i++;
74            if(i == k) x2 = x1, k <<= 1;
75        }
76        c++;
77    }
78 }
79 
80 void getFactor(LL n, vector<LL> &ans) {
81     if(isPrime(n)) return ans.push_back(n);
82     LL d = getDivisor(n);
83     getFactor(d, ans);
84     getFactor(n / d, ans);
85 }
86 
87 int main() {
88     int T; LL n;
89     scanf("%d", &T);
90     while(scanf("%I64d", &n) != EOF) {
91         if(isPrime(n)) puts("Prime");
92         else {
93             vector<LL> ans;
94             getFactor(n, ans);
95             printf("%I64d
", *min_element(ans.begin(), ans.end()));
96         }
97     }
98 }
View Code
原文地址:https://www.cnblogs.com/oyking/p/4102486.html