xmu 1099 素数测试随机算法

来源:互联网 发布:halt linux 恢复 编辑:程序博客网 时间:2024/05/02 09:18
#include <iostream>       #include <cstdio>       #include <string>       #include <stdlib.h>       using namespace std;       long long mod2(long long a,long long b,long long n)       //计算a*b%n的,防止a*b的时候超过 long long的范围       {            long long sum=0;           int i;           for(i=61;i>=0;i--)           {               sum<<=1;               if(b&( long long)1<<i)                   sum+=a;               sum%=n;           }           return sum;       }        long long mod( long long a, long long b, long long n)       //模取幕,计算a^b%n;       {            long long m=1;           int i=60;           while(!b&( long long)1<<i)               i--;           while(i>=0)           {               m=mod2(m,m,n);               if(b&( long long)1<<i)                   m=mod2(m,a,n);               i--;           }           return m;       }       bool witness( long long a, long long n)       {           int i=0;            long long t2,t=n-1;           while(t%2==0)           {               t>>=1;               i++;           }           t=mod(a,t,n);           for(;i>0;i--)           {               t2=mod2(t,t,n);               if(t2==1&&t!=1&&t!=n-1)                   return true;               t=t2;           }           if(t!=1)               return true;           return false;       }       bool miller_rabin( long long n)       {           int i;            long long t;           for(i=0;i<10;i++)//其中10是测试的次数,越大出错率越小,一般应用取10就够           {               t=(double)rand()/RAND_MAX*(n-2)+1;               if(witness(t,n))               return false;           }           return true;           //n是要测试的正数,如果是质数返回true,合数返回false       }       int main(){         int numcase;         scanf("%d",&numcase);         long long p;//p>1         while(numcase--){           scanf("%lld",&p);           if(miller_rabin(p))puts("Yes");           else  puts("No");         }         return 0;       }  

原创粉丝点击