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 }

 

posted @ 2014-08-21 00:13  再见~雨泉  阅读(893)  评论(0编辑  收藏  举报