POJ 1811 Miller_Rabin+Pollard_Rho

原创 2012年03月30日 15:23:53

赤裸裸的模板题吧

一个大数,判断是否是素数,如果是合数输出最小的因子。

大数的素数测试,随机算法Miller_Rabin测试,前提是了解费马小定理。不过对于非平方根处有疑惑,还得请教大牛

至于输出最小因子,运用Pollard_Rho即可,也算是随机算法,怎么看都是要靠RP的,至于xi=xi-1^2+c ,这个c的取法一直不理解,我用的是240,有的人是使用随机数,网上有大牛说12323速度最快?

/*
ID:cxlove
PROB:poj 1811
HINT:Miller_Rabin+Pollard_Rho
*/
#include<iostream>
#include<cstdio>
#include<ctime>
#include<cstring>
#include<cstdlib>
#define C	240
#define TIME 10
#define LL long long
using namespace std;
LL ans;
LL gcd(LL a, LL b){
	if(a==0) return 1;
	if(a<0) return gcd(-a,b);
	return b==0?a:gcd(b,a%b);
}
LL MultMod(LL a,LL b,LL n){
	a%=n;
	b%=n;
	LL ret=0;
	while(b){
		if(b&1){
			ret+=a;
			if(ret>=n) ret-=n;
		}
		a=a<<1;
		if(a>=n) a-=n;
		b=b>>1;
	}
	return ret;
}
LL PowMod(LL a,LL n,LL m){
	LL ret=1;
	a=a%m;
	while(n>=1){
		if(n&1)
			ret=MultMod(ret,a,m);
		a=MultMod(a,a,m);
		n=n>>1;
	}
	return ret;
}
bool Witness(LL a,LL n){
	LL t=0,u=n-1;
	while(!(u&1)){
		t++;
		u/=2;
	}
	LL x0=PowMod(a,u,n);
	for(int i=1;i<=t;i++){
		LL x1=MultMod(x0,x0,n);
		if(x1==1&&x0!=1&&x0!=(n-1))
			return true;
		x0=x1;
	}
	if(x0!=1)
		return true;
	return false;
}
bool Miller_Rabin(LL n,int t){
	if(n==2) return true;
	if((n&1)==0)  return false;
	srand(time(NULL));
	for(int i=0;i<t;i++){
		LL a=rand()%(n-1)+1;
		if(Witness(a,n))
			return false;
	}
	return true;
}
LL Pollard_Rho(LL n,LL c){
	LL i=1,x=rand()%n,y=x,k=2;
	while(1){
		i++;
		x=(MultMod(x,x,n)+c)%n;
		LL d=gcd(y-x,n);
		if(d!=1&&d!=n)
			return d;
		if(x==y)
			return n;
		if(i==k){
			y=x;
			k*=2;
		}
	}
}
void get_small(LL n,LL c){
	if(n==1) return;
	if(Miller_Rabin(n,TIME)){
		ans=min(n,ans);
		return ;
	}
	LL p=n;
	while(p>=n) p=Pollard_Rho(p,c--);
	get_small(p,c);
	get_small(n/p,c);
}
int main(){
	srand(time(NULL));
	LL n;
	int t;
	scanf("%d",&t);
	while(t--){		
		scanf("%I64d",&n);
		if(Miller_Rabin(n,TIME))
			printf("Prime\n");
		else{ans=n;
			get_small(n,C);
			printf("%I64d\n",ans);
		}
	}
	return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

HDU 1695 GCD 【数论,容斥原理】

求(1,b)区间和(1,d)区间里面gcd(x, y) = k的数的对数(1 b和d分别除以k之后的区间里面,只需要求gcd(x, y) = 1就可以了,这样子求出的数的对数不变。 这道题目还要求...

HDU 4335 What is N? 多校4(数论)

转载请注明出处,谢谢 http://blog.csdn.net/ACM_cxlove?viewmode=contents           by---cxlove 题目:http:/...

关于 A^x = A^(x % Phi(C) + Phi(C)) (mod C) 的若干证明

转一篇非常有用的文章,先留着 【关于 A^x = A^(x % Phi(C) + Phi(C)) (mod C) 的若干证明】【指数循环节】 以下内容全部原创,转载请注明作者 : Ae...

HDU 1695 欧拉函数+容斥原理

转载请注明出处,谢谢 http://blog.csdn.net/ACM_cxlove?viewmode=contents           by---cxlove 很NB的数论题啊。 求1~...

HDU 1695 GCD 欧拉函数+容斥原理

转载请注明出处,谢谢 http://blog.csdn.net/ACM_cxlove?viewmode=contents           by---cxlove 题目:http:/...

莫比乌斯反演的学习(HDU1695)

前两天学习了一下之前一直觉得高大上并且想学的内容——莫比乌斯反演。不过学任何东西都是一样,学会了发现也就这样,虽然只是皮毛。OK,废话不多说,进入正题,今天我用杭电的1695这道题再来温习一下莫比乌斯...

HDU1754【分块入门1】

k..
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)