[学习笔记]Pollard-Rho
之前学的都是假的
%%zzt
Miller_Rabin:Miller-Rabin与二次探测
大质数分解:
找到所有质因子,再logn搞出质因子的次数
方法:不断找到一个约数d,递归d,n/d进行分解,直到n是质数
快速幂快速乘:
ll qk(ll a,ll b,ll m){ll d=((long double)a/m*b);ll r=a*b-d*m;return ((ull)r+m)%m; } ll qm(ll x,ll y,ll mod){ll ret=1;while(y){if(y&1) ret=qk(ret,x,mod);x=qk(x,x,mod);y>>=1;}return ret; }
注意快速乘:((ull)r+m)%m由于r可能<0或者>m,这一步是必须的
Miller-Rabin:
bool M_R(ll p){if(p==1) return false;if(p==2||p==3||p==5||p==7||p==11||p==61) return true;if(p%2==0||p%3==0||p%5==0||p%7==0) return false;int s=ctz(p-1);for(reg i=0;i<6;++i){int a=pri[i];ll k=(p-1)>>s;k=qm(a,k,p);if(k==1) continue;ll las=k;for(reg j=1;j<=s;++j){k=qk(k,k,p);if(k==1&&las!=p-1&&las!=1) return false;las=k;}if(k!=1) return false;}return true; }
二进制gcd
ll gcd(ll a,ll b) {if(!a||!b) return a|b;#define ctz __builtin_ctzllint shift=ctz(a|b);b>>=shift;while(a){a>>=ctz(a);if(a<b)swap(a,b);a-=b;}return b<<shift;#undef ctz }
就是高精gcd才用的更相减损术
Pollard-Rho
主体1
ll P_R(ll p,ll c){ll x=0,y=0,d;int k=2,has=1;ll tmp=1;while(1){++has;x=ad(qk(x,x,p),c,p);tmp=qk(tmp,abs(y-x),p);if(x==y) return p;if(k==has){k<<=1;y=x;d=gcd(tmp,p);tmp=1;if(d>1) return d;}} }
注意tmp,把所有的abs(y-x)乘在一起,gcd显然不变,并且减少了求gcd次数
主体2
void fin(ll p,int cnt){if(p==1||p<=ans) return;if(M_R(p)) {ans=max(ans,p);return;}ll d=P_R(p,cnt);while(d==p) --cnt,d=P_R(p,cnt);while(p%d==0) p/=d;fin(p,cnt);fin(d,cnt); }
如果要求质因子,开个vector,最后去重即可
模板:
【模板】Pollard-Rho算法
// luogu-judger-enable-o2 #include<bits/stdc++.h> #define reg register int #define il inline #define fi first #define se second #define mk(a,b) make_pair(a,b) #define numb (ch^'0') #define pb push_back #define solid const auto & #define enter cout<<endl #define pii pair<int,int> using namespace std; typedef long long ll; template<class T>il void rd(T &x){char ch;x=0;bool fl=false;while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);for(x=numb;isdigit(ch=getchar());x=x*10+numb);(fl==true)&&(x=-x);} template<class T>il void output(T x){if(x/10)output(x/10);putchar(x%10+'0');} template<class T>il void ot(T x){if(x<0) putchar('-'),x=-x;output(x);putchar(' ');} template<class T>il void prt(T a[],int st,int nd){for(reg i=st;i<=nd;++i) ot(a[i]);putchar('\n');} namespace Modulo{ const int mod=998244353; int ad(int x,int y){return (x+y)>=mod?x+y-mod:x+y;} void inc(int &x,int y){x=ad(x,y);} int mul(int x,int y){return (ll)x*y%mod;} void inc2(int &x,int y){x=mul(x,y);} int qm(int x,int y=mod-2){int ret=1;while(y){if(y&1) ret=mul(x,ret);x=mul(x,x);y>>=1;}return ret;} } //using namespace Modulo; namespace Miracle{ ll ans; ll qk(ll x,ll y,ll mod){ll d=((long double)x*y/mod);ll r=x*y-mod*d;return r<0?r+mod:(r>=mod?r-mod:r); } ll qm(ll x,ll y,ll mod){ll ret=1;while(y){if(y&1) ret=qk(ret,x,mod);x=qk(x,x,mod);y>>=1;}return ret; } ll ad(ll x,ll y,ll mod){return (x+y)>=mod?x+y-mod:x+y; } ll gcd(ll a,ll b){if(!a||!b) return a+b;#define ctz __builtin_ctzllint tmp=ctz(a|b);b>>=ctz(b);while(a){a>>=ctz(a);if(a<b) swap(a,b);a-=b;}return b<<tmp; } int pri[6]={2,3,5,7,11,61}; bool M_R(ll p){// cout<<"M_R "<<p<<endl;if(p==1) return false;if(p==2||p==3||p==5||p==7||p==11||p==61) return true;if(p%2==0||p%3==0||p%5==0||p%7==0) return false;int s=ctz(p-1);for(reg i=0;i<6;++i){ll a=pri[i];ll tmp=(p-1)>>s;ll now=qm(a,tmp,p);if(now==1||now==p-1) continue;for(reg j=1;j<=s;++j){ll las=now;now=qk(now,now,p);if(now==1&&las!=p-1&&las!=1) return false;}if(now!=1) return false;}return true; } ll P_R(ll p,ll c){// cout<<" P_R "<<p<<" "<<c<<endl; ll x,y,d;ll tmp=1,has=1,k=2;x=y=0;while(1){++has;x=ad(qk(x,x,p),c,p);tmp=qk(tmp,abs(y-x),p);if(x==y) return p;if(has==k){k<<=1;d=gcd(tmp,p);if(d>1) {// cout<<" ret "<<d<<endl;return d;}tmp=1;y=x;}} } void sol(ll n,int c){if(n==1||n<=ans) return;if(M_R(n)){ans=max(ans,n);return;}ll d=P_R(n,c);while(d==n) --c,d=P_R(n,c);while(n%d==0) n/=d;sol(n,c);sol(d,c); } int main(){int t;rd(t);srand(19260817);while(t--){ans=0;ll n;rd(n);sol(n,19260817);if(ans!=n) printf("%lld\n",ans);else printf("Prime\n");}return 0; }} signed main(){Miracle::main();return 0; }/*Author: *Miracle* */
View Code
转载于:https://www.cnblogs.com/Miracevin/p/10858196.html
[学习笔记]Pollard-Rho相关推荐
- 《密码编码学与网络安全》William Stalling著---学习笔记(二)【知识点速过】【数字签名+密钥管理分发+用户认证】
提示:博文有点长,请保持耐心哦~ 前一篇文章: <密码编码学与网络安全>William Stalling著-学习笔记(一)[知识点速过][传统密码+经典对称加密算法+经典公钥密码算法+密码 ...
- Practical Zero-Knowledge Protocols Based on the Discrete Logarithm Assumption 学习笔记 1
1. 引言 Stephanie Bayer 2013年博士论文 <Practical Zero-Knowledge Protocols Based on the Discrete Logarit ...
- 深度学习笔记一:稀疏自编码器
开始学习深度学习了,既然确定目标就要努力前行!为自己加油!--2015.6.11 Sparse Encoder 1.神经网络 概念:假设我们有训练样本集 (x(^ i),y(^ i)) ,那么神经网络 ...
- 《基于张量网络的机器学习入门》学习笔记6
<基于张量网络的机器学习入门>学习笔记6 密度算符(密度矩阵) 具体到坐标表象 在纯态上 在混合态上 纯态下的密度算符 混合态下的密度算符 密度算符的性质 量子力学性质的密度算符描述 第一 ...
- Ceres Solver Document学习笔记
Ceres Solver Document学习笔记 Ceres Solver Document学习笔记 1. 基本概念 2. 基本方法 2.1 CostFunction 2.2 AutoDiffCos ...
- Pytorch Document学习笔记
Pytorch Document学习笔记 Pytorch Document学习笔记 1. 网络层 1.1 torch.nn.Conv2d 1.2 torch.nn.MaxPool2d / torch. ...
- 台湾大学林轩田机器学习技法课程学习笔记1 -- Linear Support Vector Machine
红色石头的个人网站:redstonewill.com 关于台湾大学林轩田老师的<机器学习基石>课程,我们已经总结了16节课的笔记.这里附上基石第一节课的博客地址: 台湾大学林轩田机器学习基 ...
- 机器学习理论《统计学习方法》学习笔记:第六章 逻辑斯谛回归与最大熵模型
机器学习理论<统计学习方法>学习笔记:第六章 逻辑斯谛回归与最大熵模型 6 逻辑斯谛回归与最大熵模型 6.1 逻辑斯谛回归模型 6.1.1 逻辑斯谛分布 6.1.2 二项逻辑斯蒂回归模型 ...
- opencv进阶学习笔记11:cannny边缘检测,直线检测,圆检测
基础版笔记传送门 python3+opencv学习笔记汇总目录(适合基础入门学习) 进阶版笔记目录链接: python+opencv进阶版学习笔记目录(适合有一定基础) cannny边缘检测 基础版边 ...
- OpenCV学习笔记(十三):霍夫变换:HoughLines(),HoughLinesP(),HoughCircles( )
OpenCV学习笔记(十三):霍夫变换:HoughLines(),HoughLinesP(),HoughCircles( ) 1.霍夫线变换HoughLines() OpenCV支持三种不同的霍夫线变 ...
最新文章
- 移动端模态窗口的滚动和橡皮筋问题解决方案
- Ubuntu中启用 ThinkPad指纹识别
- java中for循环的简化_Java中for语句的简化写法
- exadata磁盘组无法mount恢复---惜分飞
- WX: picker 滚动选择器
- 三菱fx2n64mr说明书_FX2N-64MR-001原理及应用三菱FX2N-64MR-001使用说明书 - 三菱
- 解决ros::TimeNotInitializedExcep
- git安装步骤_详解linux安装git的方法步骤(超实用)
- 苹果新一代 AirPods 能活过两年吗?
- keras TimeDistributed 描述
- 在 Mac 上拷贝(复制)、粘贴的方法
- python 数据分析实践--(1)收入预测分析
- 豆瓣八卦小组html失败,原来豆瓣有这么多稀奇古怪的小组?
- 基于聚类的个性化推荐电商案例分析总结
- 楷书书法规则_写好楷书的五条规律,不懂这些,书法就很难入门
- 春江水暖鸭先知,不破楼兰誓不还
- greenplum的用法
- 斯人已去,因荣永存(下)
- php API接口最基本的写法
- LaneLoc:基于高精地图的车道线定位