Article directory
Title (rubbish translation)
describe
Given an integer, you need to determine whether it is a prime.
input
The first line contains the number of test cases t (1<=T<=20) t (1<=T<=20) t (1 < = T < = 20), then the following T lines contain the integer N (2<=N<254) N (2 & lt; = N & lt; 2 ^ {54}) N (2 < = N < 254)
output
For each test case, if N is a Prime number, the line containing the word "Prime" is output; otherwise, the line containing the minimum Prime factor of N is output.
sample input
2
5
10
sample output
Prime
2
thinking
This question uses the Miller Rabin primality test. Point here in Bukit
Pollardpollardpollard? Rhorhorhorho is a random algorithm. Its idea is to first use Miller Miller? Rabinrabinrabin to determine whether the current number is a prime number. If so, record and return. If not, let's set the number to be decomposed as n n n, then we should look for a factor p p p of the current number, find it, and then decompose the prime factor for ppp and n/pn/pn/p respectively, which is similar to but not divide and conquer.
So, how can we quickly find the factor of the current number?
Here, we use the following method: first, we randomly generate two numbers of 1 − n1 - n1 − n, and use the absolute value of these two number differences to compare with nnn to determine whether the absolute value of these two number differences is a factor of nnn.
Here comes another question: why should we use the absolute value of the difference between two random numbers to judge whether it is one of the factors of n, instead of directly generating a random number to judge? Point here in Bukit
Steps:
The definition function f (x) = x 2 + C, ccf(x)=x^2+c, ccf(x)=x2+c, cc are given randomly
Note that since it is in the sense of modulo nnn, the value of xxx will form a ring, similar to ρ ρ
xxx takes one step at a time, yyy takes one step at a time point of 2k2^k2k (the most metaphysical part)
Each time, determine whether gcd(abs(x − y),n)gcd(abs(x − y),n)gcd(abs(x − y),n) is 1
If x=yx=yx=y, exit and random ccc again
Code
#include <cstdio> #include <cmath> #include <cstdlib> #include <iostream> using namespace std; #define LL long long LL n, ans, t; bool flag; inline LL gcd(LL a, LL b){ if( !b ) return a; return gcd(b, a%b); } inline LL ksc(LL x, LL y, LL mod){ LL sum = 0; while( y ){ if( y&1 ) sum = (sum+x)%mod; x = (x + x)%mod; y >>= 1; } return sum; } inline LL qkp(LL x, LL y, LL mod){ LL sum = 1; while( y ){ if( y&1 ) sum = ksc(x,sum,mod); x = ksc(x,x,mod); y >>= 1; } return sum; } inline bool miller_rabin(LL x){ if( x == 2 || x == 3 || x == 5 || x == 7 ) return 1; if( x < 2 || x % 2 == 0 ) return 0; LL u, p, xx; int k = 0; u = x-1; while( u%2 == 0 ){ k++; u >>= 1; } for(int i = 1; i < 11; i ++){ xx = rand()%(x-1)+1; xx = qkp(xx, u, x); p = xx; for(int j = 1; j <= k; j ++){ xx = ksc(xx, xx, x); if( p != 1 && p != x-1 && xx == 1 ) return 0; p = xx; } if( xx != 1 ) return 0; } return 1; } inline LL pollard_rho(LL x, LL c){ LL i = 1, k = 2; LL xx = rand()%x; LL y = xx; while( 1 ){ i++; xx = (ksc(xx,xx,x)+c)%x; LL d = gcd(fabs(y-xx), x); if( 1 < d && d < x ) return d; if( y == xx ) return x; if( i == k ){ y = xx; k <<= 1; } } } inline void fin_d(LL x){ if( miller_rabin(x) ){ ans = min(ans, x); return ; } LL p = x; while( p >= x ) p = pollard_rho(p, rand()%(x-1)+1); fin_d(p); fin_d(x/p); } signed main(){ scanf("%lld", &t); while( t-- ){ scanf("%lld",&n); ans = 0x3f3f3f3f3f3f3f3f; fin_d(n); if( n != ans ) printf("%lld\n", ans); else printf("Prime\n"); } return 0; }