洛谷4718【模板】Pollard-Rho算法
Description:
给定T个数,分别求出它们的最大质因数
Solution:
其实大概框架是很容易想到的
对于一个数n
找到它的一个因数x 判断这个因数是不是质数 如果是质数就更新答案
如果不是 就分别分解x与n/x
找因数用Pollar-Rho 判质数用Miller-Rabin
细节看代码QAQ
Code:
#include<bits/stdc++.h>
#define Rg register
#define go(i,a,b) for(Rg int i=a;i<=b;i++)
#define yes(i,a,b) for(Rg int i=a;i>=b;i--)
#define il inline
#define ll long long
#define ld long double
#define ull unsigned long long
using namespace std;
il ll read()
{
ll x=,y=;char c=getchar();
while(c<''||c>''){if(c=='-')y=-;c=getchar();}
while(c>=''&&c<=''){x=(x<<)+(x<<)+c-'';c=getchar();}
return x*y;
}
int T;
ll n,ans;
//-----------快速乘 快速幂 gcd f函数(生成下一个随机数的函数)
il ll mul(ll x,ll y,ll z)//一个超级快的快速乘
{
ll sm=(ld)x/z*y;
return ((ull)x*y-(ull)sm*z+z)%z;
}
il ll ksm(ll x,ll y,ll z)
{
ll ans=;
while(y)
{if(y&)ans=mul(ans,x,z);x=mul(x,x,z);y>>=;}
return ans;
}
il ll f(ll x,ll g,ll y){return (mul(x,x,y)+g)%y;}
il ll gcd(ll x,ll y){return y==?x:gcd(y,x%y);}
//-----------Miller-rabin判质数
il bool rabin(ll x,ll y)
{
if(ksm(x,y-,y)!=)return ;//费马小定理
ll z=y-,sm;
while(!(z&))
{
z>>=;sm=ksm(x,z,y);
if(sm!=&&sm!=y-)return ;//二次探测
if(sm==y-)return ;
}return ;
}
il bool miller(ll x)
{
if(x==||x==||x==||x==||x==)return ;
if(x==)return ;
return rabin(,x)&&rabin(,x)&&rabin(,x)&&rabin(,x)&&rabin(,x);
}
//-------------Pollard-Rho算法的主体
/*这里所写的Pollard-Rho算法不是最朴素的版本
是一个更快更好的版本
1.不是每次算出下一个随机数之后都算gcd,而是把算的这些数都乘起来(当然要%一下x)
累计了一定量的数之后再求一次gcd 这样就大大减少了求gcd的次数从而提高速度
这里选定的是127个数累计起来求一次gcd 为什么是127呢 因为它是个好数字(我也不知道)
2.上面的优化有局限性 就是很有可能环比较小 没到127个数就出现环 这样即使已经出现过含x因数的数也会跳出循环
遇到这样的情况就会拖慢速度 甚至永远都算不出来
这里可以用一个倍增的方法解决这个问题 分别在生成(1,2,4,8,16,32,64...)个数的时候算一次gcd
*/
il ll Pollard(ll x)
{
ll a,b,d,g,y,i,j;
while()
{
a=b=rand()%x;g=rand()%x;y=;i=;j=;
while(++i)
{
a=(mul(a,a,x)+g)%x;y=mul(y,abs(a-b),x);
if(a==b||!y)break;
if(i<||i==j)
{
d=gcd(x,y);if(d>&&d!=x)return d;
if(i==j)b=a,j<<=;
}
}
}
}
//------------递归找最小质因子
il void find(ll x)
{
if(x<=ans)return;//最优性剪枝
if(miller(x)){ans=x;return;}
ll y=Pollard(x);while(x%y==)x/=y;//判定质数 更新答案
find(y);find(x);//继续寻找
}
int main()
{
T=(int)read();
while(T--)
{
n=read();ans=;find(n);
if(ans==n){printf("Prime\n");continue;}
printf("%lld\n",ans);
}
return ;
}
洛谷4718【模板】Pollard-Rho算法的更多相关文章
- Pollard Rho算法浅谈
Pollard Rho介绍 Pollard Rho算法是Pollard[1]在1975年[2]发明的一种将大整数因数分解的算法 其中Pollard来源于发明者Pollard的姓,Rho则来自内部伪随机 ...
- Pollard Rho 算法简介
\(\text{update 2019.8.18}\) 由于本人将大部分精力花在了cnblogs上,而不是洛谷博客,评论区提出的一些问题直到今天才解决. 下面给出的Pollard Rho函数已给出散点 ...
- Miller Rabin素数检测与Pollard Rho算法
一些前置知识可以看一下我的联赛前数学知识 如何判断一个数是否为质数 方法一:试除法 扫描\(2\sim \sqrt{n}\)之间的所有整数,依次检查它们能否整除\(n\),若都不能整除,则\(n\)是 ...
- 洛谷P3373 [模板]线段树 2(区间增减.乘 区间求和)
To 洛谷.3373 [模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格 ...
- Pollard rho算法+Miller Rabin算法 BZOJ 3668 Rabin-Miller算法
BZOJ 3667: Rabin-Miller算法 Time Limit: 60 Sec Memory Limit: 512 MBSubmit: 1044 Solved: 322[Submit][ ...
- 初学Pollard Rho算法
前言 \(Pollard\ Rho\)是一个著名的大数质因数分解算法,它的实现基于一个神奇的算法:\(MillerRabin\)素数测试(关于\(MillerRabin\),可以参考这篇博客:初学Mi ...
- 洛谷P3375 [模板]KMP字符串匹配
To 洛谷.3375 KMP字符串匹配 题目描述 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置. 为了减少骗分的情况,接下来还要输出子串的前缀数组next.如果 ...
- LCT总结——概念篇+洛谷P3690[模板]Link Cut Tree(动态树)(LCT,Splay)
为了优化体验(其实是强迫症),蒟蒻把总结拆成了两篇,方便不同学习阶段的Dalao们切换. LCT总结--应用篇戳这里 概念.性质简述 首先介绍一下链剖分的概念(感谢laofu的讲课) 链剖分,是指一类 ...
- 【AC自动机】洛谷三道模板题
[题目链接] https://www.luogu.org/problem/P3808 [题意] 给定n个模式串和1个文本串,求有多少个模式串在文本串里出现过. [题解] 不再介绍基础知识了,就是裸的模 ...
- 洛谷-P5357-【模板】AC自动机(二次加强版)
题目传送门 -------------------------------------- 过年在家无聊补一下这周做的几道AC自动机的模板题 sol:AC自动机,还是要解决跳fail边产生的重复访问,但 ...
随机推荐
- BZOJ2069 POI2004ZAW(最短路)
显然这样的路径一定是选择了与1相邻的不同的两点分别作为起点和终点(除1本身).如果能将每一组起点终点都计算到就可以得出最优解了.暴力显然不行.注意到我们每次求出的是单源最短路径,考虑如何充分利用信息. ...
- NOIP2014题解
NOIP2014题解 Day1 生活大爆炸版石头剪刀布 rps 简单模拟题,注意细节 #include<iostream> #include<cstdio> using nam ...
- LOJ [#115. 无源汇有上下界可行流](https://loj.ac/problem/115)
#115. 无源汇有上下界可行流 先扔个板子,上下界的东西一点点搞,写在奇怪的合集里面 Code: #include <cstdio> #include <cstring> # ...
- luogu1984 烧水问题 (找规律)
为了节省能量,我们会希望一个已经烧开了的水温度越低越好 那么可以得到结论,它要依次去碰当前温度从大到小的水 然后再把温度最高的烧开呗 可是直接模拟会T 稍微写一写大概能找到每次烧开花费能量的一个规律 ...
- Linux:打印(输出)所有的列(awk, $0)
如果想输出所有的列的话,只需要$0这个函数,例如以下命令: awk '/rs16945916/ {print $0}' test.txt > allcol.txt rs16945916指的是打印 ...
- Java 多线程间通信
JDK 1.5 以后, 将同步和锁封装成了对象, 并将操作锁的隐式方法定义到了该对象中, 将隐式动作变成了显示动作. Lock 接口 Lock 接口, 位于 java.util.concurrent. ...
- 清除ul li里面的浮动并让ul自适应高度的一个好办法
有时候会遇到ul li列表里面的东西会用到浮动,这个时候ul的高度就不会被撑开,这怎么办呢? 1)最笨的方法就是设置ul的高度,但这种方法很死板,高度不能自适应 2)有次我试着在ul里面加一个清除浮动 ...
- H3C配置FTP服务器
H3C配置FTP服务器 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.FTP协议简介 1.FTP协议是互联网上广泛使用的文件传输协议 FTP文件传送协议(File Transf ...
- LVS+keepalived 的DR模式的两种做法
LVS DR模式搭建 准备工作 三台机器: dr:192.168.13.15 rs1:192.168.13.16 rs2: 192.168.13.17 vip:192.168.13.100 修改DR上 ...
- JAVA记录-redis缓存机制介绍(三)
Redis 事务 Redis 事务可以一次执行多个命令, 并且带有以下两个重要的保证: 事务是一个单独的隔离操作:事务中的所有命令都会序列化.按顺序地执行.事务在执行的过程中,不会被其他客户端发送来的 ...