[学习笔记]Pollard-Rho
之前学的都是假的
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=;
while(y){
if(y&) ret=qk(ret,x,mod);
x=qk(x,x,mod);
y>>=;
}
return ret;
}
注意快速乘:((ull)r+m)%m由于r可能<0或者>m,这一步是必须的
Miller-Rabin:
bool M_R(ll p){
if(p==) return false;
if(p==||p==||p==||p==||p==||p==) return true;
if(p%==||p%==||p%==||p%==) return false;
int s=ctz(p-);
for(reg i=;i<;++i){
int a=pri[i];
ll k=(p-)>>s;
k=qm(a,k,p);
if(k==) continue;
ll las=k;
for(reg j=;j<=s;++j){
k=qk(k,k,p);
if(k==&&las!=p-&&las!=) return false;
las=k;
}
if(k!=) return false;
}
return true;
}
二进制gcd
ll gcd(ll a,ll b)
{
if(!a||!b) return a|b;
#define ctz __builtin_ctzll
int 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=,y=,d;
int k=,has=;
ll tmp=;
while(){
++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<<=;
y=x;
d=gcd(tmp,p);
tmp=;
if(d>) return d;
}
}
}
注意tmp,把所有的abs(y-x)乘在一起,gcd显然不变,并且减少了求gcd次数
主体2
void fin(ll p,int cnt){
if(p==||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==) p/=d;
fin(p,cnt);fin(d,cnt);
}
如果要求质因子,开个vector,最后去重即可
模板:
// 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=;bool fl=false;while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
for(x=numb;isdigit(ch=getchar());x=x*+numb);(fl==true)&&(x=-x);}
template<class T>il void output(T x){if(x/)output(x/);putchar(x%+'');}
template<class T>il void ot(T x){if(x<) 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=;
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-){int ret=;while(y){if(y&) ret=mul(x,ret);x=mul(x,x);y>>=;}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<?r+mod:(r>=mod?r-mod:r);
}
ll qm(ll x,ll y,ll mod){
ll ret=;
while(y){
if(y&) ret=qk(ret,x,mod);
x=qk(x,x,mod);
y>>=;
}
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_ctzll
int 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[]={,,,,,};
bool M_R(ll p){
// cout<<"M_R "<<p<<endl;
if(p==) return false;
if(p==||p==||p==||p==||p==||p==) return true;
if(p%==||p%==||p%==||p%==) return false;
int s=ctz(p-);
for(reg i=;i<;++i){
ll a=pri[i];
ll tmp=(p-)>>s;
ll now=qm(a,tmp,p);
if(now==||now==p-) continue;
for(reg j=;j<=s;++j){
ll las=now;
now=qk(now,now,p);
if(now==&&las!=p-&&las!=) return false;
}
if(now!=) return false;
}
return true;
}
ll P_R(ll p,ll c){
// cout<<" P_R "<<p<<" "<<c<<endl;
ll x,y,d;
ll tmp=,has=,k=;
x=y=;
while(){
++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<<=;
d=gcd(tmp,p);
if(d>) {
// cout<<" ret "<<d<<endl;
return d;
}
tmp=;
y=x;
}
}
}
void sol(ll n,int c){
if(n==||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==) n/=d;
sol(n,c);sol(d,c);
}
int main(){
int t;
rd(t);
srand();
while(t--){
ans=;ll n;rd(n);
sol(n,);
if(ans!=n) printf("%lld\n",ans);
else printf("Prime\n");
}
return ;
} }
signed main(){
Miracle::main();
return ;
} /*
Author: *Miracle*
*/
[学习笔记]Pollard-Rho的更多相关文章
- OpenCV之Python学习笔记
OpenCV之Python学习笔记 直都在用Python+OpenCV做一些算法的原型.本来想留下发布一些文章的,可是整理一下就有点无奈了,都是写零散不成系统的小片段.现在看 到一本国外的新书< ...
- OpenCV 学习笔记 07 目标检测与识别
目标检测与识别是计算机视觉中最常见的挑战之一.属于高级主题. 本章节将扩展目标检测的概念,首先探讨人脸识别技术,然后将该技术应用到显示生活中的各种目标检测. 1 目标检测与识别技术 为了与OpenCV ...
- UFLDL深度学习笔记 (一)反向传播与稀疏自编码
UFLDL深度学习笔记 (一)基本知识与稀疏自编码 前言 近来正在系统研究一下深度学习,作为新入门者,为了更好地理解.交流,准备把学习过程总结记录下来.最开始的规划是先学习理论推导:然后学习一两种开源 ...
- UFLDL深度学习笔记 (五)自编码线性解码器
UFLDL深度学习笔记 (五)自编码线性解码器 1. 基本问题 在第一篇 UFLDL深度学习笔记 (一)基本知识与稀疏自编码中讨论了激活函数为\(sigmoid\)函数的系数自编码网络,本文要讨论&q ...
- matlab学习笔记9 高级绘图命令_1 图形对象_根对象,轴对象,用户控制对象,用户菜单对象
一起来学matlab-matlab学习笔记9 高级绘图命令_1 图形对象_根对象,轴对象,用户控制对象,用户菜单对象 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考书籍 <matl ...
- matlab学习笔记8 基本绘图命令-特殊图形绘制
一起来学matlab-matlab学习笔记8 基本绘图命令_3 特殊图形绘制 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考书籍 <matlab 程序设计与综合应用>张德丰等 ...
- 【python】numpy库和matplotlib库学习笔记
Numpy库 numpy:科学计算包,支持N维数组运算.处理大型矩阵.成熟的广播函数库.矢量运算.线性代数.傅里叶变换.随机数生成,并可与C++/Fortran语言无缝结合.树莓派Python v3默 ...
- 【学习笔记】Polya定理
笔者经多番周折终于看懂了\(\text{Burnside}\)定理和\(\text{Polya}\)定理,特来写一篇学习笔记来记录一下. 群定义 定义:群\((G,·)\)是一个集合与一个运算·所定义 ...
- js学习笔记:webpack基础入门(一)
之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...
- PHP-自定义模板-学习笔记
1. 开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2. 整体架构图 ...
随机推荐
- JS黑科技
1.论如何优雅的取随机字符串 Math.random().toString(16).substring(2) // 13位 Math.random().toString(36).substring(2 ...
- 【OI】位运算操作
一.基础操作 1.a<<b 将二进制a左移b位,不够的地方用0补位 例如 100<<2 == 10000 2.a>>b 将二进制a右移b位 例如 100>&g ...
- Intellij IDEA通过tomcat部署web项目的机制
问题 以前使用eclipse调用tomcat运行web项目时,eclipse的方式非常直接了当,就是直接将项目更新到%TOMCAT_HOME%/webapps目录下即可.然而在使用Intellij I ...
- jQuery迷你帮助查找功能
在线演示 本地下载
- Vim学习与总结
1. :w 后面可以加文件名 2. 使用hjkl 来移动光标,当然你也可以使用箭头.j就是向下的箭头,k是向上,h向左, l向右 3. :help <command> → 显示相关命令的 ...
- hdu1080 LCS变形
dp[i][j]表示配对的最大值. dp[i-1][j]表示s1[i-1]与'-'配对. dp[i][j-1]表示s2[j-1]与'-'配对. dp[i-1][j-1]表示s1[i-1]与s2[j-1 ...
- 查看JAVA占用CPU高的线程日志
# . 查看主进程占用cpu高 top # java # . 按照线程占用cpu由高到低进行排查: -o THREAD,tid, # USER %CPU PRI SCNT WCHAN USER SYS ...
- XML内部DTD约束 Day24
<?xml version="1.0" encoding="UTF-8"?> <!-- 内部DTD --> <!-- XML:ex ...
- Java练习 SDUT-1184_拍皮球
C语言实验--拍皮球 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 小瑜3岁了,很喜欢玩皮球,看来今后喜欢打篮球的^_ ...
- 1月北上广P2P平台之最 平台数成交量现双降
1月北上广P2P平台之最 平台数成交量现双降 今日(2月9日),网贷之家联合盈灿咨询发布了<北上广地区P2P网贷行业2017年1月月报>.月报数据显示,截至2017年1月底,北京.上海 ...