Online JudgeProblem SetAuthorsOnline ContestsUser
Web Board
Home Page
F.A.Qs
Statistical Charts
Problems
Submit Problem
Online Status
Prob.ID:
Register
Update your info
Authors ranklist
Current Contest
Past Contests
Scheduled Contests
Award Contest
User ID:
Password:
  Register

我的代码,一直WA, 谁给我根绳子上吊吧!!!

Posted by liuyuyangfoam at 2005-12-24 14:47:25 on Problem 1811
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

bool isPrime(__int64 n);
bool miller_rabin(__int64 n,int s);
bool witness(__int64 a,__int64 n);
__int64 modular_exponentiation(__int64 a,__int64 u,__int64 n);
void pollard_rho(__int64 n);
void factorizer(__int64 n); // for n <= 1024*1024
int binary_length(__int64 x);
__int64 euclid(__int64 a,__int64 b);
__int64 euclid_stein(__int64 a,__int64 b);
__int64 rand64();


__int64 min;

int primes[173] = {2, 3, 4, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013, 1019, 1021};

int main()
{
	srand((unsigned)time(NULL));		
    int t,i;	// the number of test cases, 1 <= t <= 20	
	__int64 n;
    scanf("%d",&t);	
	for (i=0;i<t;i++) {		
		scanf("%I64d",&n);		
		if (isPrime(n)) 
			printf("%s\n","Prime");		
		else
		{			
			min = n;
			pollard_rho(n);			
			printf("%I64d\n",min);
		}			
	}  	
    return 0;
}
//////////////////////////////////////////////////////////
/*
int main()
{	
	__int64 i=1050028,j,p;
	while(1)
	{
		next:
		i++;
		printf("%I64d\n",i);
		min = i;
		if (isPrime(i)) 
			{printf("%s\n","Prime");continue;	}
		else 
			printf("%s\n","Composite");	

		pollard_rho(i);
		p = min;
		//is prime?
		
		for(j=2;j<=sqrt(i);j++)
		{
			if (i%j==0){

				if (j!=p) {printf("pollard WRONG!!!! %I64d j:%I64d p:%I64d\n ",i,j,p);return 1;}
				goto next;
			}
			
		}
		if (!isPrime(i)) {printf("isPrime WRONG!!!! %I64d\n",i);return 1;}		
		
		
	}
	return 0;
	
	
	//pollard_rho(4);
	//printf("%I64d\n",min);
}
*/
////////////////////////////////////////////////
// 2 < N < 2^54
bool 
isPrime(__int64 n) 
{
	int j;
	if (n==1) 
		return false;
	for (j=0;j<173;j++)
	{
		if (n==primes[j]) return true;
		if (n%primes[j]==0) return false; // n is composite.
	}	
	
	return miller_rabin(n,50);	// s取50应该差不多了
}

bool 
miller_rabin(__int64 n,int s)
{
	int j;
	__int64 a;
	for (j=1;j<=s;j++) {
		// Make sure that a is in [ 1, n - 1 ].
		a = rand64()%(n-1)+1;
		if (witness(a,n))
			return false;
	}
	return true;
}


bool 
witness(__int64 a,__int64 n)
{
	__int64 u=n-1,z=0,j;	
	while (u%2==0) 
	{
		u=u/2;
		z++;
	}
	__int64 x0 = modular_exponentiation(a,u,n),x1;
	for (j=1;j<=z;j++) 
	{
		x1 = x0*x0%n;
		if (x1==1&&x0!=1&&x0!=n-1)
			return true;
		x0=x1;
	}
	if (x1!=1) return true;
	return false;
}

// a^b mod n, 算法到论 Corollary 31.35
__int64 
modular_exponentiation(__int64 a,__int64 b,__int64 n) 
{	
	__int64 c=0, d=1;
	int i;	
	for (i=binary_length(b)-1;i>=0;i--)
	{
		c=c*2;
		d=(d*d)%n;
		if (b&(1<<i))
		{
			c = c + 1;
			d = ( d * a ) % n;
		}
	}
	return d;
}

// 返回x用二进制表示的长度
int 
binary_length(__int64 x)
{
	int result = 0;
	while (x>0)
	{
		x=x>>1;
	}
	return result;
}

__int64
rand64()
{
	__int64 result = 0;	
	int i;
	
	for (i=0;i<=62;i++)
	{
		if (rand()%2==0) result = result|1LL<<i;		
	}
	result = result|1;		// 保证为奇数
	result = result|1LL<<62;	// 保证足够的长	
	return result;
}


void 
pollard_rho(__int64 n)
{	
	if (n<=1048576/* 1024*1024 */) {factorizer(n);return;}
		
	__int64 i = 1;
	__int64 x1 = rand64() % n;	
	__int64 y = x1;
	__int64 d;
	__int64 k = 2;	

	while(1)
	{
		i++;
///		printf("n:%I64d x1:%I64d\n",n,x1);
		x1 = (x1 * x1 -1) % n;
		//d = euclid_stein(abs(y-x1), n);
		d = euclid(abs(y-x1), n);
		if (d!=1 && d!=n)
		{
			if (d < min) min = d;
			if (!isPrime(d)) 
			{
				pollard_rho(d);
			}
			if (n/d < min) min = n/d;			
			if (!isPrime(n/d))
			{
				pollard_rho(n/d);
			}		 
///			printf("d:%I64d\n",d);
			return;
		}
        if (i==k) {
         	y=x1;
            k*=2;
        }		
	}	
}




void 
factorizer(__int64 n)
{
	int j;
	for (j=0;j<173;j++)
	{
		if (n%primes[j]==0) {if (min>primes[j]) min=primes[j];return;}
	}
}


// 欧几里德,求最大公约数
__int64 
euclid(__int64 a,__int64 b)
{
	if (b==0) return a;
	else return euclid(b,a%b);
}


/*
Euclid & stein 算法
与传统的Euclid算法不同的是它只有移位和加减法.
*/
/*
__int64
euclid_stein(__int64 a,__int64 b)
{
	__int64 temp;
    if(a < b)   //arrange so that a>b
	{
		temp = a; 
        a = b; 
        b = temp; 
    } 
    if ( !b )    // the base case, b == 0 
        return a; 
    if (((a&1) == 0 ) && ( (b&1) == 0 ))	//a and b are even 
        return euclid_stein( a>>1, b>>1 )<<1; 
    else if ( (b&1) )	// only a is even 
        return euclid_stein( a>>1, b ); 
    else if ( (a&1) )	// only b is even 
        return euclid_stein( a, b>>1 ); 
	else
		return euclid_stein( b, (a-b)>>1 );	// a and b are odd 
}
*/

Followed by:

Post your reply here:
User ID:
Password:
Title:

Content:

Home Page   Go Back  To top


All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator