首页 > 代码库 > POJ 1811Prime Test(米勒拉宾素数测试)

POJ 1811Prime Test(米勒拉宾素数测试)

直接套用模板,以后接着用

这里还有一个素因子分解的模板

  1 #include <map>  2 #include <set>  3 #include <stack>  4 #include <queue>  5 #include <cmath>  6 #include <ctime>  7 #include <vector>  8 #include <cstdio>  9 #include <cctype> 10 #include <cstring> 11 #include <cstdlib> 12 #include <iostream> 13 //#include <algorithm> 14 using namespace std; 15 #define INF 0x3f3f3f3f 16 #define inf ((LL)1<<40) 17 #define lson k<<1, L, mid 18 #define rson k<<1|1, mid+1, R 19 #define mem0(a) memset(a,0,sizeof(a)) 20 #define mem1(a) memset(a,-1,sizeof(a)) 21 #define mem(a, b) memset(a, b, sizeof(a)) 22 #define FOPENIN(IN) freopen(IN, "r", stdin) 23 #define FOPENOUT(OUT) freopen(OUT, "w", stdout) 24 template<class T> T ABS ( T a) { return a >= 0 ? a : -a;   } 25 template<class T> T CMP_MIN ( T a, T b ) { return a < b;   } 26 template<class T> T CMP_MAX ( T a, T b ) { return a > b;   } 27 template<class T> T MAX ( T a, T b ) { return a > b ? a : b; } 28 template<class T> T MIN ( T a, T b ) { return a < b ? a : b; } 29 template<class T> T GCD ( T a, T b ) { return b ? GCD ( b, a % b ) : a; } 30 template<class T> T LCM ( T a, T b ) { return a / GCD ( a, b ) * b;     } 31 template<class T> void SWAP( T& a, T& b ) { T t = a; a = b;  b = t;     } 32  33 typedef __int64 LL; 34 //typedef long long LL; 35 const int MAXN = 10005; 36 const int MAXM = 110000; 37 const double eps = 1e-14; 38 const double PI = 4.0 * atan(1.0); 39  40  41  42  43 LL n, ans; 44 int t; 45  46  47  48  49 #define Times 10 50  51 //产生[0, n-1]的一个随机数 52 LL random(LL n) 53 { 54     return ((double)rand() / RAND_MAX * n + 0.5); 55 } 56 //乘法,采用加法模拟,避免中间结果超出LL 57 LL multi(LL a,LL b,LL mod) 58 { 59     LL ans=0; 60     while(b) 61     { 62         if(b & 1) 63         { 64             b--; 65             ans=(ans+a) % mod; 66         } 67         else 68         { 69             b/=2; 70             a=(2*a) % mod; 71         } 72     } 73     return ans; 74 } 75  76 //快速幂,同样避免超出LL的做法 77 LL Pow(LL a, LL b, LL mod) 78 { 79     LL ans=1; 80     while(b) 81     { 82         if(b&1) 83         { 84             b--; 85             ans=multi(ans,a,mod); 86         } 87         else 88         { 89             b/=2; 90             a=multi(a,a,mod); 91         } 92     } 93     return ans; 94 } 95  96 //miller_rabin的一遍探测,返回false表示是合数 97 bool witness(LL a,LL n) 98 { 99     LL d=n-1;100     while( !(d&1) )101         d >>= 1;102     LL t=Pow(a, d, n);103     while(d!=n-1 && t!=1 && t!=n-1)104     {105         t=multi(t,t,n);106         d<<=1;107     }108     return t==n-1 || d&1;109 }110 111 //miller_rabin算法,返回false表示是合数,否则是素数112 //返回素数出错的概率(最高)为 1 / (4 ^ times)113 bool miller_rabin(LL n)114 {115     if(n == 2)116         return true;117     if( n<2 || !(n&1) )118         return false;119     for(int i = 1; i <= Times ; i++ )120     {121         LL a = random(n-2) + 1;122         if( !witness(a, n) )123             return false;124     }125     return true;126 }127 128 129 //************************************************130 //pollard_rho 算法进行质因数分解131 //************************************************132 LL factor[100];//质因数分解结果(刚返回时是无序的)133 int tol;//质因数的个数。数组小标从0开始134 135 LL gcd(LL a,LL b)136 {137     if(a==0)return 1;//???????138     if(a<0) return gcd(-a,b);139     while(b)140     {141         LL t=a%b;142         a=b;143         b=t;144     }145     return a;146 }147 148 LL Pollard_rho(LL x, LL c)149 {150     LL i=1,k=2;151     LL x0=rand()%x;152     LL y=x0;153     while(1)154     {155         i++;156         x0=(multi(x0, x0, x) + c) % x;157         LL d=gcd(y-x0,x);158         if(d!=1&&d!=x) return d;159         if(y==x0) return x;160         if(i==k){y=x0;k+=k;}161     }162 }163 164 //对n进行素因子分解165 void findfac(LL n)166 {167     if(miller_rabin(n))//素数168     {169         factor[tol++]=n;170         ans = MIN(ans, n);171         return;172     }173     LL p=n;174     while(p>=n)175         p=Pollard_rho(p, rand()%(n-1)+1);176     findfac(p);177     findfac(n/p);178 }179 180 181 182 int main()183 {184     //FOPENIN("in.txt");185     while(~scanf("%d", &t))while(t--)186     {187         ans = inf;188         scanf("%I64d", &n);189         findfac(n);190         if(miller_rabin(n))191             printf("Prime\n");192         else printf("%I64d\n", ans);193     }194     return 0;195 }