您的位置:首页 > 其它

poj 1811(素数测定以及因子分解)

2011-08-28 16:29 375 查看
写了好长时间。。。。。看了好长时间的算法导论。。。唉。。。

#include<iostream>
#include<ctime>
using namespace std;
long long p,ans;
// 素数测试
long long mod2(long long a,long long b,long long n)
{
long long  exp = a%n, res = 0;
while(b)
{
if(b&1)
{
res += exp;
if(res>n) res -= n;
}
exp <<= 1;
if(exp>n)
exp -= n;

b>>=1;
}
return res;
}
// ret = (a^b)%n
long long mod(long long a,long long p,long long m)
{
long long exp=a%m, res=1; //
while(p>=1)
{
if(p&1)//
res=mod2(res,exp,m);
exp = mod2(exp,exp,m);
p>>=1;
}
return res;
}
//miller-rabin法测试素数, time 测试次数
bool miller_rabin(long long n)
{
if(n==2)return 1;
if(n<2||!(n&1))return 0;

long long a, u=n-1, x, y;
int t=0;
while(u%2==0){
t++;
u/=2;
}
srand(time(0));
for(int i=0;i<8;i++)
{
a = rand() % (n-1) + 1;
x = mod(a, u, n);
for(int j=0;j<t;j++)
{
y = mod2(x, x, n);
if ( y == 1 && x != 1 && x != n-1 )
return false; //must not
x = y;
}
if( y!=1) return false;
}
return true;
}
// 因子分解
long long gcd(long long a,long long b){
long long c;
while(b){
c=b; b=a%b; a=c;
}
return a;
}
long long pollard_rho(long long n,long long k){
srand(time(0));
long long x=rand()%(n-1)+1;
long long i=1,t=2,y=x,d;
while(1){
i++;
x=(mod2(x,x,n)+k)%n;
d=gcd(y-x,n);
if(d>1 && d<n) return d;
if(x==y) return n;
if(t==i) y=x,t<<=1;
}
}
void get_factor(long long n,long long k){
if(miller_rabin(n)){
p++;
if(p>1) ans=min(ans,n);
else ans=n;
return ;
}
long long p=n;
while(p>=n)
p=pollard_rho(p,k--);
get_factor(p,k);
get_factor(n/p,k);
}
int main(int argc, char** argv) {
int cas;
long long n;
scanf("%d",&cas);
while(cas--){
scanf("%lld",&n);
if(miller_rabin(n))
puts("Prime");
else{
p=0;
get_factor(n,107);
printf("%lld\n",ans);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: