SPOJ PON - Prime or Not

题目链接http://www.spoj.com/problems/PON/

题目大意:判断N是不是素数,N<264-1.

解题思路:需要用到拉宾-米勒素性判定。

(选自数论书籍)合数的拉宾-米勒测试:设n是奇素数,记n-1=2kq,q为奇数。对不被n整除的某个a,如果下述两个条件都成立,则n是合数。

  a): aq !≡ 1 (mod n),   即a的q次方不与1模n同余

  b): 对所有i = 0,1,2,……,k-1, a2^i * q !≡ -1 (mod n) 

所以可以打出100个素数表然后迭代判定。其中需要用的:快速幂取模,大数乘取模。

代码:

 1 const int maxn = 1e5 + 10;
 2 VI primes;
 3 bool vis[maxn];
 4 
 5 ll mul_mod(ll a, ll b, ll m){
 6     ll ans = 0, base = a;
 7     while(b){
 8         if(b & 1) ans = (ans + base) % m;
 9         base %= m;
10         base = base * 2 % m;
11         b >>= 1;
12     }
13     return ans;
14 }
15 ll pow_mod(ll a, ll b, ll m){
16     ll ans = 1, base = a % m;
17     while(b){
18         if(b & 1) ans = mul_mod(ans, base, m);
19         base %= m;
20         base = mul_mod(base, base, m);
21         b >>= 1;
22     }
23     return ans % m;
24 }
25 void dowork(){
26     memset(vis, 0, sizeof(vis));
27     for(int i = 2; i < maxn / 2; i++)
28         for(int j = i * 2; j > 0 && j < maxn; j += i)
29             vis[j] = 1;
30     for(int i = 2; i < 1e5; i++)
31         if(!vis[i]) primes.push_back(i);
32 }
33 bool check(ll x){
34     if(x == 2) return true;
35     if(x % 2 == 0) return false;
36     ll q = x - 1;
37     int k = 0;
38     while(!(q & 1)){
39         k++; q >>= 1;
40     } 
41     bool flag = true;
42     for(int i = 0; i < 100; i++){
43         ll a = primes[i];
44         if(a == x) return true;
45         if(pow_mod(a, q, x) == 1) 
46             continue;
47         bool none = true;
48         for(int j = 0; j < k; j++){
49             ll qi = 1 << j;
50             ll tmp = pow_mod(a, qi * q, x);
51             if(tmp == x - 1){
52                 none = false;
53                 break;
54             }
55             else if(tmp == 1) 
56                 break;
57         }
58         if(none) {
59             flag = false;
60             break;
61         }
62     }
63     return flag;
64 }
65 int main(){
66     dowork();
67     int t;
68     scanf("%d", &t);
69     while(t--){
70         ll n;
71         scanf("%lld", &n);
72         if(check(n)) puts("YES");
73         else puts("NO");
74     }
75 }

题目:

PON - Prime or Not

 

Given the number, you are to answer the question: "Is it prime?"

Solutions to this problem can be submitted in C, C++, Pascal, Perl, Python, Ruby, Lisp, Hask, Ocaml, Prolog, Whitespace, Brainf**k and Intercal only.

Input

t – the number of test cases, then t test cases follows. [t <= 500]
Each line contains one integer: N [2 <= N <= 2^63-1]

Output

For each test case output string "YES" if given number is prime and "NO" otherwise.

Example

Input:
5
2
3
4
5
6

Output:
YES
YES
NO
YES
NO

 

 
posted @ 2017-09-11 14:31  EricJeffrey  阅读(448)  评论(0编辑  收藏  举报