**I have been obsessed with this magical method of determining the Gender and have no time to understand it. By studying "Mathematical basics of Information Security", I learned this determination method.**

**First, let's prove the ferma's theorem.**

**If P is a prime number and gcd (A, P) = 1, a ^ (p-1 = 1 (mod p) exists)**

**Based on the following theorem**

**If (A, P) = 1, {x | (x, P) = 1} is a completely residual system under model P, then {ax | (x, P) = 1} is also a fully surplus system under the modulo p.**

**Another {0, 1, 2,... P-1} is the next residual system of model P.**

**Therefore,**

**{A * 0, A * 1, A * 2,... a * (p-1)} is the completely residual system under model P.**

**And a * 0 = 0 (mod P), remove**

**Take the remaining 1-1, with a * 1 = K1 (mod p) A * 2 = k2 (mod p )... A * (p-1) = k_p-1 (mod P), where K1... k_p-1 is 1, 2 ,... an arrangement of the first 1.**

**Therefore, a * 1 * a * 2... * a * P-1) = 1*2 *... * (p-1) (mod P)**

**That is, a ^ P-1 * (p-1 )! = (PM )! (Mod P)**

**P is also a prime number, so gcd (p-1 )!, P) = 1**

**So it is the same as Division (PM )! Still true, get the Fermat theorem.**

**The theory is as follows: days without code****Let's talk about how to detect prime numbers.**With galaxy

Miller-Rabin detection relies on the following theorem:

If P is a prime number, X is a positive integer smaller than P, and x ^ 2 = 1 mod P, X is either 1 or P-1.

Simple Proof: If x ^ 2 = 1 mod p, p is divisible by x ^ 2-1, that is, the total Division (x + 1) (x-1), Because p is a prime number, so P either divide x + 1, or divide the X-1, the former x P-1 the latter X is 1.

The Theorem above illustrates that if any positive integer x smaller than P finds that the non-ordinary square root of 1 (modulp) exists, p is the sum.

We can always express this as U2 ^ t, where u is an odd number and T is a positive integer. At this point:

That is, you can calculate a ^ u first, and then calculate a ^ (p-1) after a consecutive T-square, and find the extraordinary square root at any square, then it is determined that p is the sum.

For example, 560 = 35*2 ^ 4, so u = 35, t = 4:

Since a non-ordinary square root 67 is found, we can assert that 561 is a sum. Therefore, 2 is an evidence that 561 is a combination of numbers.

**###### To discuss Miller-Rabin's tests, we must first prove a theorem (Lamma )#######**

If P is a prime number greater than 2, if a number is the same as 1 or-1 modulo n (that is, x = 1 (mod P) or X =-1 (mod p), it is called an extraordinary square root of 1 modulo n.

In fact, there is no extraordinary square root of 1 modulo p. (Note: The ordinary root refers to 1 or-1 (mod P), otherwise it is not an ordinary root .)

Proof: Assume that X is an extraordinary square root of 1 modulo p, then there are:

Because X is extraordinary, there is (x + 1) and (x-1) and X mutual quality, that is to say (x + 1) and (x-1) cannot be divisible by P, therefore (x + 1) (x-1) cannot be divisible by P, leading to contradictions.

Therefore, there is no extraordinary square root of 1 modulo p. Certificate completion

**-------- The key is coming ------------**

Now we want n to be an odd number, and (n-1) can be expressed in the form of 2 S · d, where S and D are both positive integers. Then, according to the theory of ferma's small theorem, as we can see from the above-mentioned theory, the key to this problem is that if the square modulo p of X is 1, then the x modulo p must be-1 or 1, and P may be a prime number, otherwise, it must be a combination. If the square modulo p of X is-1, the x modulo p is not required. Therefore, 2R · d must follow the above rules in the r process. In this way, the miller-Rabin kernel Testing Algorithm is obtained:

**% Miller-labin algorithm %**

Determine whether a number p is a prime number (P must first be a positive integer greater than or equal to 2 to be a prime number). First, determine the parity. If it is an even number, only 2 is a prime number, if it is an odd number (here we can consider removing the multiples of 3 or even 5), we will first find D. For each bottom a, multiply d by 2 until it is (p-1)/2, in this process (including the original D and D = (p-1)/2 ), let's set T to the remainder of the D Power modulo p of A. (1) when T =-1 jumps out, it is declared that P may be a prime number (2) when T = 1, if D is an odd number, P may be a prime number. Otherwise, P must be a Union number. (3) when D = (p-1)/2, P must be a Union number. ,

**-------- Important: Coming soon ------------**

To determine whether N is a prime number, for N in a certain range, it can be guaranteed that it is a deterministic algorithm as long as the base of a in a certain range. The following details:

- If
*N*<1,373,653, it is enough to test*A*= 2 and 3.
- If
*N*<9,080,191, it is enough to test*A*= 31 and 73.
- If
*N*<4,759,123,141, it is enough to test*A*= 2, 7, and 61.
- If
*N*<2,152,302,898,747, it is enough to test*A*= 2, 3, 5, 7, and 11.

The first three of them should be relatively useful, especially the third one. It is an order of magnitude with longint! Very easy to use !!!

The Miller-Rabin primatlity test algorithm can check whether a large number is a prime number with a high probability. The algorithm is described as follows:

**Input**:

*N*> 3, an odd integer to be tested for primality;

**Input**:

*K*, A parameter that determines the accuracy of the test

**Output**:

*Composite*If

*N*Is composite, otherwise

*Probably Prime*
**01:**Write

*N*−1 as 2

*S*·

*D*With

*D*Odd by factoring powers of 2 from

*N*−1

**02:**Loop: Repeat

*K*Times:

**03:**Pick

*A*Randomly in the range [2,

*N*− 2]

**04:**
*X*Bytes

*A*
*D*MoD

*N*
**05:**If

*X*= 1 or

*X*=

*N*−1 then do next loop

**06:**For

*R*= 1 ..

*S*−1

**07:**
*X*Bytes

*X*2 mod

*N*
**08:**If

*X*= 1 then return

*Composite*
**09:**If

*X*=

*N*−1 then do next loop

**10:**Return

*Composite*
**11:**Return

*Probably Prime*
The idea behind this algorithm is: if*A* *D*= 1 (mod*N*) And*N*= 1 + 2*S*·*D*Is a prime number, then the value sequence

*A*
*D*MoD

*N*,

*A*2

*D*MoD

*N*,

*A*4

*D*MoD

*N*,...,

*A*2

*S*
*D*MoD

*N*
It will end with 1, and the value of the front edge of the first 1 will be*N*-1 (when*P*When it is a prime number,*Y*2 then 1 (mod*P*), The only solution is*Y*≡ ± 1 (mod*P*), Because (*Y*+ 1 )(*Y*-1) must be*P*). Note that if*N*-1, the next value in the sequence must be 1. Because :(*N*-1) 2 bytes*N*2-2*N*+ 1 then 1 (mod*N*). In this algorithm:

- This algorithm is used to determine an odd number greater than 3.
*N*Whether it is a prime number. Parameters*K*Used to determine*N*Is the probability of a prime number.
- This algorithm can definitely determine
*N*It is a combination, but it can only be said*N* **Possible**Is a prime number.
- Line 2:
*N*-1 is decomposed into 2*S*·*D*Format, here*D*Is an odd number.
- Line 3: cycle the following steps (lines 02nd to 10)
*K*Times.
- Row 3, ◇ in [2,
*N*-2] Select a positive integer independently and randomly in the range*A*.
- In row 3, ◇ calculate the first value of the sequence:
*X*Bytes*A**D*MoD*N*.
- Row 3, ◇ if the first number of the sequence is 1 or
*N*-1: meets the preceding conditions,*N*It may be a prime number. It is converted to 03rd rows for a next loop.
- 06th rows, ◇ execute 07th to 09 rows cyclically, and traverse the remaining
*S*-1 value.
- Line 3, ◇ calculate the next value of the sequence:
*X*Bytes*X*2 mod*N*.
- Row 3, ◇ if this value is 1, but the value of the front edge is not
*N*-1, does not meet the above conditions, therefore*N*It must be a combination of numbers. The algorithm ends.
- Row 3, ◇ if this value is
*N*-1, so the next value must be 1, which meets the preceding conditions,*N*It may be a prime number. It is converted to 03rd rows for the next loop.
- In the first row, ◇ it is found that the sequence does not end with 1 and does not meet the preceding conditions. Therefore, N must be the sum and the algorithm ends.
- In row 11th, K independently and randomly selected a values have been tested. Therefore, n is very
**Possible**It is a prime number and the algorithm ends.

During a test, the maximum error rate of this algorithm is 1/4. If we select*A*Repeat the test once the algorithm reports*N*If it is a combination, we can be sure*N*Certainly not a prime number. However, if this algorithm repeatedly checks 25 reports*N*It may be a prime number, so we can say*N*"It is almost certainly a prime number ". This is because the probability of an error message about its input is less than (1/4) 25 in such a 25-time test process. This opportunity is less than 1015 points. Even if we have verified billions of different prime numbers in such a process, the probability of an error is expected to be less than one thousandth. Therefore, if an error occurs, it is better to say that our computer has lost one in its computing because of hardware failure or cosmic ray. Such probabilistic algorithms enable us to raise a question mark on traditional reliability standards: do we really need a strict proof of adequacy. (The above text is referenced by Donald E. "algorithm P (probability detection)" in "4.5.4 factorization factor" On page 2nd of "computer programming art 3rd semi-numerical algorithm (version 359th)" by knuth)

Spoj 288 determines whether a number within 2 ^-1 is a prime number (because a large number is required, it is written in Python)

import randomdef QuickPow(a, b, MOD): ret = 1 tmp = a%MOD while b>0: if (b&1): ret = (ret*tmp)%MOD tmp = (tmp*tmp)%MOD b >>= 1 return retdef Miller_Rabin(a, p): # a^(p-1) = 1 (mod p) p1 = p-1 s2 = p1 & -p1 # fetch the last 1 x = QuickPow(a, p1//s2, p) if x == 1 or x == p1: return True while s2>1: x = (x*x)%p if x == 1: return False if x == p1: return True s2 >>= 1 return Falsedef IsPrime(p, k): if p == 2 or p == 3: return True if p < 2 or (p&1) == 0: return False for i in range(k): if not Miller_Rabin(random.randint(2, p-1), p): return False return Truen = int(input())for i in range(n): p = int(input()) print(‘YES‘ if IsPrime(p, 1) else ‘NO‘)

View Code uses C ++ to write a Miller-Rabin template. I don't know why there are several errors (including tests) at the bottom of the above three numbers in Int) test with a random number of five. The range of 10 ^ 8 is only one error, but it is strange that the range of 10 ^ 9 is normal.

#include <cstdio>#include <ctime>#include <cstdlib>using namespace std;int x;inline long long QuickPow(long long a,long long n,long long MOD){ long long ret=1,tmp=a%MOD; while(n){ if(n&1) ret=ret*tmp%MOD; tmp=tmp*tmp%MOD; n>>=1; } return ret;}inline bool Miller_Rabin(int x, int a) // a^(x-1) = 1 (mod x){ int tmx=x-1; int s2=tmx & -tmx; long long res=QuickPow(a, tmx/s2, x); if(res == 1 || res == tmx) return 1; while(s2>1) { res=(res*res)%x; if(res == 1) return 0; if(res == tmx) return 1; s2>>=1; } return 0;}inline bool IsPrime(int x, int k){ if(x == 2 || x == 3) return 1; if(x < 2 || x%2 == 0 || x%3 == 0) return 0; while(k--) if(!Miller_Rabin(x, rand()%(x-2)+2)) return 0; return 1;}bool pd[10000005];int main(){ srand(time(NULL)); pd[1]=1; int count=0; for(int i=1; i<=10000000; i++) { if(IsPrime(i, 5) == pd[i]) count++; if(!pd[i]) for(int j=i+i; j<=10000000; j+=i) pd[j]=1; } printf("%d\n", count); return 0;}

View code

Miller-rapin learning from the kernel Test