\(Pollard-Rho\)算法学习笔记
我愿称之为\(RP\)算法
算是咕咕咕了很久的一个知识点,今天补一补(主要是\(T2\)考了就很寄)
好像我昨天跳到了这个题时候说\(:\)这个东西谁也不会考吧。今天就开幕雷击了
首先是\(Miller-Rabin\)判断素性
一个玄学(基于随机的算法),莫名很喜欢这个算法。。。
常用的判断素性方法,\(O(\sqrt n)\)暴力枚举,\(n<=10^{18}\)完美\(TLE\)
基础数论里面的费马小定理
\(a^{\phi(p)-1}=1(\mod p)\)当\((1<=a
逆否命题成立,假如存在\((1<=a,那么\(p\)不为质数
我们可以随机选择数字,快速幂判断素性
但是即使满足了所有\((1<=a这个数也不一定是质数
那么就需要进行二次检验
若满足\(x^2=1(\mod p)\)的解为\(x=±1(\mod p)\)
具体流程\(:\)
\(p\)是奇数,那么\(p-1\)是偶数,随机选取底数\(a\)
\(a^{p-1}=1\),然后\(d=\frac{(p-1)}{2}\),相当于对\(a\)开根号继续判断
最后是奇数时候只需判断是否\(a^d\neq ±1(\mod p)\),相当于求解上一步的根就好了
那么关于\(Pollard-Rho\)算法
基本过程\(:\)
随机数,两两做差,判断是否成环,之后判断即可
#define Eternal_Battle ZXK
#include
#define int long long
using namespace std;
mt19937_64 rd(random_device{}());
int T,in;
int MO(int x,int mod)
{
if(x>=1;
}
return res;
}
bool test(int x,int r,int t,int mod)
{
x=my_pow(x,r,mod);
if(x==1||x==mod-1) return false;
for(int i=1;i>=1,t++;
for(int i:{2,3,5,7,11,13,17,19,23,29,31,37})
{
if(x==i) return true;
if(test(i,r,t,x)) return false;
}
return true;
}
int gcd(int a,int b)
{
if(!a) return b;
if(!b) return a;
int t=__builtin_ctzll(a|b);
a>>=__builtin_ctzll(a);
do
{
b>>=__builtin_ctzll(b);
if(a>b){long long t=b;b=a,a=t;}
b-=a;
}
while(b);
return a<(2,x-1))(rd),b=a;
int c=(uniform_int_distribution(1,x-1))(rd),d=1;
while(d==1)
{
a=MO((int)((__int128_t)a*a%x)+c,x);
b=MO((int)((__int128_t)b*b%x)+c,x);
b=MO((int)((__int128_t)b*b%x)+c,x);
d=gcd(abs(a-b),x);
if(d==x) return Getp(x);
}
return d;
}
vector Getys(int x)
{
vectorys;
queueq;
q.push(x);
while(!q.empty())
{
int now=q.front();
q.pop();
if(mlrb(now)) ys.push_back(now);
else
{
int y=Getp(now);
q.push(y);
q.push(now/y);
}
}
return ys;
}
signed main()
{
scanf("%lld",&T);
while(T--)
{
scanf("%lld",&in);
vectorys=Getys(in);
if(ys.size()==1) puts("Prime");
else
{
int Max=0;
sort(ys.begin(),ys.end());
cout<