poj 1811

Miller_Rabin大素数探定还有  pollard_rho质因数分解。

TL了三次,肯定不是算法不行,应该是存在死循环了。

/*
poj 1811 prime test
result:AC
time:329MS
language:c++
memory:168K
*/
#include"stdio.h"
#include"time.h"
#include"iostream"
using namespace std;
int pri[]={2,3,5,7,11,13,17,19,23,29};
__int64 gcd(__int64 a,__int64 b)
{
	while(b)
	{
		__int64 c=a%b;
		a=b;
		b=c;
	}
	return a;
}
__int64 product_mod(__int64 a,__int64 b,__int64 n){
	__int64 tmp=0;
	while(b){
		if(b&1){
			tmp+=a;
			if(tmp>=n)
				tmp-=n;
		}
		a<<=1;
		if(a>=n)a-=n;
		b>>=1;
	}
	return tmp;
}
__int64 power_mod(__int64 a,__int64 m,__int64 n)
{
	__int64 tmp=1;
	a%=n;
	while(m)
	{
		if(m&1) tmp=product_mod(tmp,a,n);
		a=product_mod(a,a,n);
		m>>=1;
	}
	return tmp;
}
bool Miller_Rabin(__int64 n)
{
	if(n<2)
		return false;
	if(n==2)
		return true;
	if(!(n&1))
		return false;
	__int64 k=0,i,j,m,a;
	m=n-1;
	while(!(m&1)) m>>=1,k++;
	for(i=0;i<10;i++)
	{
		if(pri[i]>=n)
			return true;
		a=power_mod(pri[i],m,n);
		if(a==1) continue;
		for(j=0;j<k;j++)
		{
			if(a==n-1)
				break;
			a=product_mod(a,a,n);
		}
		if(j==k)
			return false;
	}
	return true;
}
__int64 pollard_rho(__int64 c,__int64 n)
{
	__int64 i,x,y,k,d;
	i=1;
	x=y=rand()%n;
	k=2;
	do{
		i++;
		d=gcd(n+y-x,n);
		if(d>1&&d<n)
			return d;
		if(i==k) y=x,k<<=1;
		x=(product_mod(x,x,n)+n-c)%n;
	}while(y!=x);
	return n;
}
__int64 rho(__int64 n)
{
	if(Miller_Rabin(n))
		return n;
	__int64 t=n;
	while(t>=n)
		t=pollard_rho(rand()%(n-1)+1,n);
	__int64 a=rho(t);
	__int64 b=rho(n/t);
	return a<b?a:b;
}
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		__int64 n;
		scanf("%I64d",&n);
		if(Miller_Rabin(n))
			printf("Prime\n");
		else {
			printf("%I64d\n",rho(n));
		}

	}
	return 0;
}

posted @ 2011-05-25 21:02  Ac_smile  阅读(354)  评论(0编辑  收藏  举报