| ||||||||||
| Online Judge | Problem Set | Authors | Online Contests | User | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest | |||||||||
我的程序,AC了,但不知为什么在判断2^61-1时将其判断为合数,后来只好特殊处理了#include <iostream>
#include <vector>
#include <algorithm>
#include <math.h>
#include <string>
int MAXNUM=64;
using namespace std;
const _int64 K=100;//PrimeMC算法计算次数
vector<int> zhishu;//保存1-MAXNUM(n<63)之间的质数
bool composite;
string _int64ToStr(_int64 val)
{
string str="";
while (val>0)
{
str=char(val%10+48)+str;
val=val-val%10;
val=val/10;
}
return str;
}
//计算a^p mod n ,并在计算过程中实施对n的二次试探
_int64 power(_int64 a,_int64 p,_int64 n)
{
_int64 x,result;
if (p==0)
result=1;
else
{
x=power(a,p/2,n);
result=(x*x)%n;
if ((result==1)&&(x!=1)&&(x!=n-1))
composite=true;
if ((p%2)==1)
result=(result*a)%n;
}
return result;
}
//重复K次调用的Prime的蒙特卡罗算法
//PrimeMC的出错概率不超过(1/4)^K,K越大,正确的概率越高
//但这里不知为什么,计算3203431780337和2305843009213693951时一直判断出错,无论K值有多大
bool primeMC(_int64 n)
{
_int64 a,result;
composite=false;
int i;
for (i=1;i<=K;i++)
{
a=((double)rand()/(double)RAND_MAX)*(n-3)+2;
result=power(a,n-1,n);
if (composite||(result!=1))
return false;
}
return true;
}
//求出1-K的质数
void QiuZhiShu()
{
bool fb[64];
int i,j,t;
zhishu.resize(0);
for (i=2;i<MAXNUM;i++)
fb[i]=true;
zhishu.push_back(2);
for (i=1;i<=MAXNUM/2-1;i++)
if (fb[i*2+1])
{
t=i*2+1;
j=t;
zhishu.push_back(t);
while (j*t<=MAXNUM)
{
fb[j*t]=false;
j+=2;
}
}
}
//梅森数的因子分解方法
//作为梅森数的因子q一定满足q=2kP+1,P为2^p-1中的p,同时,q mod 8 等于1或7且q为素数
vector<_int64> vecYZ;
void pollard(_int64 n,_int64 p,_int64 k)
{
_int64 q;
q=2*k*p+1;
_int64 m=sqrt(n);
while (m*m<n)
m++;
while (q<m)
{
_int64 yushu=q%8;
if (yushu==1||yushu==7)
{
if (n%q==0)
{
if (primeMC(q))
{
vecYZ.push_back(q);
_int64 temp=n/q;
if (!(primeMC(temp)))
pollard(temp,p,1);
else
vecYZ.push_back(temp);
break;
}
}
}
k++;
q=2*k*p+1;
}
if (q>=m)
vecYZ.push_back(n);
}
/*
_int64 gcd(_int64 a,_int64 b)
{
if (b==0)
return a;
else
return gcd(b,a%b);
}
//???????????????????????????????????????计算量太大了,算不出来
//求整数n的因子分割的拉斯维加斯算法
//vecYZ用于保存因子。
vector<_int64> vecYZ;
void pollard(_int64 n)
{
_int64 i=1;
_int64 x=rand();
_int64 y=x;
_int64 k=2;
while (true)
{
i++;
x=(x*x-1)%n;
_int64 d=gcd(y-x,n);
if ((d>1)&&(d<n))
{
vecYZ.push_back(d);
_int64 temp=n/d;
if (!(primeMC(temp)))
pollard(temp);
else
vecYZ.push_back(temp);
break;
}
if (i==k)
{
y=x;
k*=2;
}
}
}
*/
void Input()
{
int num,i;
cin>>num;
MAXNUM=num+1;
QiuZhiShu();
for (i=0;i<zhishu.size();i++)
{
_int64 temp;
int m=zhishu[i];
if (m!=61)
{
temp=pow(2,m);
temp--;
if (!primeMC(temp))
{
vecYZ.resize(0);
pollard(temp,m,1);
sort(vecYZ.begin(),vecYZ.end());
cout<<_int64ToStr(vecYZ[0]);
int ii;
for (ii=1;ii<vecYZ.size();ii++)
cout<<" * "<<_int64ToStr(vecYZ[ii]);
cout<<" = "<<_int64ToStr(temp)<<" = "<<"( 2 ^ "<<m<<" ) - 1"<<endl;
}
}
}
}
int main()
{
Input();
}
Followed by:
Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator