您的位置:首页 > 其它

poj1811(Miller-Rabin(素数测试)与Pollard rho(整数的因子分解))

2013-08-17 20:19 417 查看
地址:http://poj.org/problem?id=1811

Prime Test

Time Limit: 6000MS Memory Limit: 65536K
Total Submissions: 26694 Accepted: 6587
Case Time Limit: 4000MS
Description
Given a big integer number, you are required to find out whether it's a prime number.
Input
The first line contains the number of test cases T (1 <= T <= 20 ), then the following T lines each contains an integer number N (2 <= N < 254).
Output
For each test case, if N is a prime number, output a line containing the word "Prime", otherwise, output a line containing the smallest prime factor of N.
Sample Input
2
5
10

Sample Output
Prime
2


题意:看一个数是不是素数,不是的话输出其最小素数因子。

网上找的模版(http://xingyezhi.diandian.com/post/2012-02-26/15529645

#include<cmath>
#include<ctime>
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
#define MAX (pow(2.0,60))
#define LL __int64
LL MIN;
LL gcd(LL a,LL b)
{
if(b==0)
return a;
else return gcd(b,a%b);
}
LL num_mul(LL a,LL b,LL n)
{
LL s=0;a%=n;
while(b)
{
if(b&1)
{
s+=a;
if(s>n) s-=n;
}
a=a<<1;
if(a>n) a-=n;
b=b>>1;
}
return s;
}
LL num_quar(LL a,LL b,LL n)
{
LL s=1;
a%=n;
while(b)
{
if(b&1)
s=num_mul(s,a,n);
a=num_mul(a,a,n);
b=b>>1;
}
return s;
}
bool miller_test(LL a,LL n)
{
LL x,y,m;
int i,j=0;
m=n-1;x=0;
while(m%2==0)
{
j++;m=m>>1;
}
x=num_quar(a,m,n);
for(i=1;i<=j;i++)
{
y=num_quar(x,2,n);
if((y==1)&&(x!=1)&&(x!=n-1))
return true;
x=y;
}
if(y!=1) return true;
return false;
}
bool times_miller(int times,LL n)
{
LL a;
int i;
if(n==1) return false;
if(n==2) return true;
if(n%2==0) return false;
srand(time(NULL));
for(i=1;i<=times;i++)
{
a=rand()%(n-1)+1;
if(miller_test(a,n))
return false;
}
return true;
}
LL pollard(LL n,int c)
{
LL i,k,x,y,d;
srand(time(NULL));
i=1;k=2;
x=rand()%n;y=x;
while(true)
{
i++;
x=(num_mul(x,x,n)+c)%n;
d=gcd(y-x,n);
if(d>1&&d<n)
return d;
if(y==x) return n;
if(i==k)
{
y=x;k=k<<1;
}
}
}
void get_small(LL n,int c)
{
LL m;
if(n==1) return ;
if(times_miller(12,n))
{
if(n<MIN)
MIN=n;
return ;
}
m=n;
while(m==n)
m=pollard(n, c--);
get_small(m,c);
get_small(n/m,c);
}
int main()
{
LL m,t;
scanf("%I64d",&t);
while(t--)
{
scanf("%I64d",&m);
if(times_miller(12,m))
puts("Prime");
else
{
MIN=MAX;
get_small(m,240);
printf("%I64d\n",MIN);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  hdu