Pollard-Rho算法学习笔记

PollardRho算法学习笔记

我愿称之为RP算法

算是咕咕咕了很久的一个知识点,今天补一补(主要是T2考了就很寄)

好像我昨天跳到了这个题时候说:这个东西谁也不会考吧。今天就开幕雷击了

首先是MillerRabin判断素性

一个玄学(基于随机的算法),莫名很喜欢这个算法。。。

常用的判断素性方法,O(n)暴力枚举,n<=1018完美TLE

基础数论里面的费马小定理

aϕ(p)1=1(modp)(1<=a<p)

逆否命题成立,假如存在(1<=a<p)ap11,那么p不为质数

我们可以随机选择数字,快速幂判断素性

但是即使满足了所有(1<=a<p)ap1=1(modp),这个数也不一定是质数

那么就需要进行二次检验

若满足x2=1(modp)的解为x=±1(modp)

具体流程:

p是奇数,那么p1是偶数,随机选取底数a

ap1=1,然后d=(p1)2,相当于对a开根号继续判断

最后是奇数时候只需判断是否ad±1(modp),相当于求解上一步的根就好了

那么关于PollardRho算法

基本过程:

随机数,两两做差,判断是否成环,之后判断即可

#define Eternal_Battle ZXK #include<bits/stdc++.h> #define int long long using namespace std; mt19937_64 rd(random_device{}()); int T,in; int MO(int x,int mod) { if(x<mod) return x; return x-mod; } int my_pow(int a,int b,int mod) { int res=1; while(b) { if(b&1) { res=((__int128_t)res*a)%mod; } a=(__int128_t)a*a%mod; b>>=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<t;i++) { x=(__int128_t)x*x%mod; if(x==mod-1) return false; } return true; } bool mlrb(int x) { if(x<2) return false; int t=0,r=(x-1); while(r%2==0) r>>=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<<t; } int Getp(int x) { if(x==1) return x; if(x&1^1) return 2; int a=(uniform_int_distribution<long long>(2,x-1))(rd),b=a; int c=(uniform_int_distribution<long long>(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<int> Getys(int x) { vector<int>ys; queue<int>q; 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); vector<int>ys=Getys(in); if(ys.size()==1) puts("Prime"); else { int Max=0; sort(ys.begin(),ys.end()); cout<<ys[ys.size()-1]<<"\n"; } } }

__EOF__

本文作者Eternal_Battle
本文链接https://www.cnblogs.com/Eternal-Battle/p/16100309.html
关于博主:这个世界除了你,都知道我喜欢你
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   Gnomeshgh_k  阅读(39)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
点击右上角即可分享
微信分享提示