洛谷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边产生的重复访问,但 ...
随机推荐
- codeforces500B
New Year Permutation CodeForces - 500B User ainta has a permutation p1, p2, ..., pn. As the New Year ...
- mysql 启动和关闭外键约束
在MySQL中删除一张表或一条数据的时候,出现 [Err] 1451 -Cannot delete or update a parent row: a foreign key constraint f ...
- BZOJ2141排队——树状数组套权值线段树(带修改的主席树)
题目描述 排排坐,吃果果,生果甜嗦嗦,大家笑呵呵.你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家 乐和和.红星幼儿园的小朋友们排起了长长地队伍,准备吃果果.不过因为小朋友们的身高有所区别 ...
- java强引用,软引用,弱引用,虚引用
java强引用,软引用,弱引用,虚引用 原文:https://blog.csdn.net/liaodehong/article/details/52223354 用了Java怎么长时间一直不知道原来J ...
- MT【4】坐标平移后齐次化
简答:通过坐标平移可以将A点移到原点,设BC:mx’+ny’=1,联立坐标变换后的椭圆方程和BC,将$\frac{y}{x}$看成斜率k,得到关于k的一元二次方程,由题意两根之积为-1,可得.
- IScroll的那些事——内容不足时下拉刷新
之前项目中的列表是采用的IScroll,但是在使用IScroll有一个问题就是:当内容不足全屏的时候,是木有办法往下拉的,这样就达不到刷新的目的了.[这是本人工作中遇到的,具体例子具体分析,这里只作一 ...
- HTML 百度地图API调用示例源码
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...
- MySql 主辅-一主多辅
MySql 主辅-一主多辅mysql tar源码包安装 骤及过程,以供参考 系统是centos6.x .注意:此安装是默认CentOS下已经安装了最新工具包,比如GNU make, GCC, Perl ...
- py3+requests+urllib+bs4+threading,爬取斗图图片
实现原理及思路请参考我的另外几篇爬虫实践博客 py3+urllib+bs4+反爬,20+行代码教你爬取豆瓣妹子图:http://www.cnblogs.com/UncleYong/p/6892688. ...
- 【UR #17】滑稽树前做游戏
假装看懂的样子 假装会做的样子 UOJ Round #17 题解 加上一个(t-w)^c,c是和i相连的点的度数 是一个多项式的话可以归纳证明 一些具体实现: 多项式存储,保留t,y, f=ai*t^ ...