rabin 素性检验 随机化算法
1 #include <cstdio> 2 #include <cstdlib> 3 #include <ctime> 4 typedef long long int LL; 5 inline bool qpow(int a,int x) 6 { 7 int b = x-1,ans = 1; 8 while(b) 9 { 10 if(b&1) ans = (LL)ans*a%x; 11 a = (LL)a*a%x; 12 b >>= 1; 13 } 14 if(ans == 1) return true; 15 else return false; 16 } 17 inline bool rabin(int x,int t) 18 { 19 for(int i=0; i<t; ++i) 20 { 21 srand(time(NULL)); 22 int a = rand()%x; 23 if(a ==0) 24 { 25 --i; 26 continue; 27 } 28 if(!qpow(a,x)) return false; 29 } 30 return true; 31 } 32 33 int main() 34 { 35 // freopen("in.txt","r",stdin); 36 int n,r; 37 while(~scanf("%d",&r)) 38 { 39 int cnt =0; 40 for(int i=0; i<r; ++i) 41 { 42 scanf("%d",&n); 43 if(rabin(n,100)) ++cnt; 44 } 45 printf("%d\n",cnt); 46 } 47 return 0; 48 }
上面是代码,主要运用费马定理,如果n是质数,有a^(n-1) %n = 1.
有定理:随机化生成小于n的正整数a,检验a^(n-1)%n 是否为1,如果n是质数,回答是的可能性为1,如果是合数,回答是的可能性不会超过1/2.所以检验多次,都回答的是YES,那么n为质数的可能性就相当高了,能任意接近于1.(这个定理怎么来的我觉得书上的证明不是很能让我信服···,它说对于两个不能通过检验的数a和b,a*b也不会通过检验····)
在检验时用快速幂。
上面在周恒明的《算法之道》的99页有详细介绍。