Pollard's Rho算法简单总结

先贴一份代码在这。

最近几天实在是太忙了没时间更新了。

代码

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cctype>
#include <algorithm>
#include <ctime>
#define rin(i,a,b) for(int i=(a);i<=(b);i++)
#define rec(i,a,b) for(int i=(a);i>=(b);i--)
#define trav(i,a) for(int i=head[(a)];i;i=e[i].nxt)
typedef long long LL;
using std::cin;
using std::cout;
using std::endl;

inline LL read(){
	LL x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
	return x*f;
}

LL n,ans,mi[6]={2,3,5,7,11,13};

inline LL gcd(LL x,LL y){
	if(!x||!y) return x+y;
	while(y){
		std::swap(x,y);
		y%=x;
	}
	return x;
}

inline LL qpow(LL x,LL y,LL mod){
	LL ret=1,tt=x%mod;
	while(y){
		if(y&1) ret=(__int128)ret*tt%mod;
		tt=(__int128)tt*tt%mod;
		y>>=1;
	}
	return ret;
}

bool miller_rabin(LL num){
	if(num<2) return 0;
	if(num==2||num==3||num==5||num==7||num==11||num==13) return 1;
	if(num%2==0||num%3==0||num%5==0||num%7==0||num%11==0||num%13==0) return 0;
	LL temp=num-1;int cnt2=0;
	while(!(temp&1)) temp>>=1,cnt2++;
	rin(i,0,5){
		LL now=qpow(mi[i],temp,num);
		if(now==1||now==num-1) continue;
		rin(j,1,cnt2){
			now=(__int128)now*now%num;
			if(now==num-1) break;
			if(j==cnt2) return 0;
		}
	}
	return 1;
}

LL pollard_rho(LL num){
	LL fixx=rand()%(num-1)+1,siz=2,x=fixx,fac=1;
	LL b=rand()%(num-1)+1;
	while(fac==1){
		rin(i,1,siz){
			x=((__int128)x*x+b)%num;
			fac=gcd(std::abs(x-fixx),num);
			if(fac>1) return fac;
		}
		siz<<=1;
		fixx=x;
	}
}

void getdivisor(LL num){
	if(num==1||num<=ans) return; 
	if(miller_rabin(num)){
		ans=std::max(ans,num);
		return;
	}
	LL x=num;
	while(x==num) x=pollard_rho(x);
	while(num%x==0) num/=x;
	if(num<x) std::swap(num,x);
	getdivisor(num);
	getdivisor(x);
}

int main(){
	int T=read();
	while(T--){
		n=read();
		ans=1;
		getdivisor(n);
		if(ans==n) printf("Prime
");
		else printf("%lld
",ans);
	}
	return 0;
}
原文地址:https://www.cnblogs.com/ErkkiErkko/p/10211738.html