数论

Miller-Rabin 素数判断

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int T=10;
ll n;
ll fp(ll a,ll r,ll p){
	ll res=1;
	for(;r;r>>=1){
		if(r&1) res=(res*a)%p;
		a=(a*a)%p;
	}
	return res;
} 
bool millerrabin(ll x){
	if(x==2) return 1;
	if(x==1) return 0;
	if(x%2==0) return 0;
	ll a=x-1;
	while(a%2==0) a/=2;
	for(int i=1;i<=T;i++){
		ll b=rand()%(x-2)+2;
		ll c=fp(b,a,x);
		if(c==1) continue;
		else{
			int f=1;
			for(int j=a;j<x&&j>=0;c=(c*c)%x,j*=2)
				if(c==x-1){
				    f=0;
					break;	
			    }
			if(f) return 0;
		}
	}
	return 1;
}
int main(){
	srand(time(NULL));
	scanf("%lld",&n);
	if(millerrabin(n)) printf("YES");
	else printf("NO");
	return 0;
}

Pollard-Rho

找因数

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int T=10;
const int C=128;
ll n;
ll gcd(ll x,ll y){
	if(y==0) return x;
	return gcd(y, x%y);
}
ll fp(ll a,ll r,ll p){
	ll res=1;
	for(;r;r>>=1){
		if(r&1) res=(res*a)%p;
		a=(a*a)%p;
	}
	return res;
} 
bool millerrabin(ll x){
	if(x==2) return 1;
	if(x==1) return 0;
	if(x%2==0) return 0;
	ll a=x-1;
	while(a%2==0) a/=2;
	for(int i=1;i<=T;i++){
		ll b=rand()%(x-2)+2;
		ll c=fp(b,a,x);
		if(c==1) continue;
		else{
			int f=1;
			for(int j=a;j<x&&j>=0;c=(c*c)%x,j*=2)
				if(c==x-1){
				    f=0;
					break;	
			    }
			if(f) return 0;
		}
	}
	return 1;
}
ll pollardrho(ll x){
	if(x==4) return 2;
	if(millerrabin(x)) return x;
	while(1){
		ll c=rand()%(n-1)+1;
		ll a=0,b=0,p=1,q=0;
		while(1){
			for(int i=0;i<C;i++){
				a=(a*a+c)%x;
				b=(b*b+c)%x;
				b=(b*b+c)%x;
				q=p*abs(a-b)%x;
				if(a==b||q==0) break;
				p=q;
			}
			ll d=gcd(p,x);
			if(d>1) return d;
			if(a!=b) break;
		}
	}
}
int main(){
	srand(time(NULL));
	scanf("%lld",&n);
	if(millerrabin(n)) printf("%lld",n);
	else printf("%lld",pollardrho(n));
	return 0;
}
posted @ 2022-08-12 13:35  KevinLikesCoding  阅读(39)  评论(0编辑  收藏  举报