【技能点】Pollard_Rho算法(大数质因数分解)

玄学随机

大体方法是,令 x = r a n d ( ) , c = r a n d ( ) x=rand(),c=rand() x=rand(),c=rand()
然后执行 y = x , x = x ∗ x + c , g = g c d ( y − x , p ) y=x,x=x*x+c,g=gcd(y-x,p) y=x,x=xx+c,g=gcd(yx,p)

经大佬多次测试发现, g > 1 g>1 g>1的概率非常高,然后我们就得到了其中一个因数。

但是这种随机生成的方法有可能会出现环,所以玄学判一下emm

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<queue>
#include<ctime>
#define ll long long
#define ull unsigned long long
#define ld long double
#define inl inline
#define re register
#define MAXN 10100
using namespace std;
inl ll ksc(ull x,ull y, ll p){return (x*y-(ull)((ld)x/p*y)*p+p)%p;}
inl ll ksm(ll x,ll y,ll p)
{
	ll res=1;
	for(;y;y>>=1,x=ksc(x,x,p))if(y&1)res=ksc(res,x,p);
	return res;
}
inl ll Abs(ll x){return x<0?-x:x;}
inl ll gcd(ll x,ll y)
{
    ll z;
    while(y){z=x;x=y;y=z%y;}
    return x;
}
inl bool mr(ll x,ll p)
{
	if(ksm(x,p-1,p)!=1)return 0;
	ll y=p-1,z;
	while(!(y&1))
	{
		y>>=1;z=ksm(x,y,p);
		if(z!=1&&z!=p-1)return 0;
		if(z==p-1)return 1;
	}
	return 1;
}
ll te_pri[20]={0,2,3,5,7,43,61,24251};
int te_num=7;
inl bool isprime(ll x)
{
	if(x<2)return 0;
	for(int i=1;i<=te_num;i++)
		if(x==te_pri[i])return 1;
	for(int i=1;i<=te_num;i++)
		if(!(x%te_pri[i])||!mr(te_pri[i],x))return 0;
	return 1;
}
inl ll rho(ll p)
{
	ll x,y,z,c,g;
	re int i,j;
	while(1)
	{
		y=x=rand()%p;
		z=1,c=rand()%p;
		i=0,j=1;
		while(++i)
		{
			x=(ksc(x,x,p)+c)%p;
			z=ksc(z,Abs(y-x),p);
			if(x==y||!z)break;
			if(!(i%127)||i==j)
			{
				g=gcd(z,p);
				if(g>1)return g;
				if(i==j)y=x,j<<=1;
			}
		}
	}
}
ll ys[1010];//最后的质数分解在ys中 
int ind;//每次重新使用ind记得清零 
inl void prho(ll p)
{
	if(p==1)return ;
	if(isprime(p)){ys[++ind]=p;return ;}
	ll pi=rho(p);
	while(p%pi==0)p/=pi;
	prho(pi);
	prho(p);
}
ll x,pos;
int main()
{
	srand(time(0));
	cin>>x;
	prho(x);
	sort(ys+1,ys+ind+1);
	int m=unique(ys+1,ys+ind+1)-ys-1;
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值