传送门

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算法的更多相关文章

  1. Pollard Rho算法浅谈

    Pollard Rho介绍 Pollard Rho算法是Pollard[1]在1975年[2]发明的一种将大整数因数分解的算法 其中Pollard来源于发明者Pollard的姓,Rho则来自内部伪随机 ...

  2. Pollard Rho 算法简介

    \(\text{update 2019.8.18}\) 由于本人将大部分精力花在了cnblogs上,而不是洛谷博客,评论区提出的一些问题直到今天才解决. 下面给出的Pollard Rho函数已给出散点 ...

  3. Miller Rabin素数检测与Pollard Rho算法

    一些前置知识可以看一下我的联赛前数学知识 如何判断一个数是否为质数 方法一:试除法 扫描\(2\sim \sqrt{n}\)之间的所有整数,依次检查它们能否整除\(n\),若都不能整除,则\(n\)是 ...

  4. 洛谷P3373 [模板]线段树 2(区间增减.乘 区间求和)

    To 洛谷.3373 [模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格 ...

  5. Pollard rho算法+Miller Rabin算法 BZOJ 3668 Rabin-Miller算法

    BZOJ 3667: Rabin-Miller算法 Time Limit: 60 Sec  Memory Limit: 512 MBSubmit: 1044  Solved: 322[Submit][ ...

  6. 初学Pollard Rho算法

    前言 \(Pollard\ Rho\)是一个著名的大数质因数分解算法,它的实现基于一个神奇的算法:\(MillerRabin\)素数测试(关于\(MillerRabin\),可以参考这篇博客:初学Mi ...

  7. 洛谷P3375 [模板]KMP字符串匹配

    To 洛谷.3375 KMP字符串匹配 题目描述 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置. 为了减少骗分的情况,接下来还要输出子串的前缀数组next.如果 ...

  8. LCT总结——概念篇+洛谷P3690[模板]Link Cut Tree(动态树)(LCT,Splay)

    为了优化体验(其实是强迫症),蒟蒻把总结拆成了两篇,方便不同学习阶段的Dalao们切换. LCT总结--应用篇戳这里 概念.性质简述 首先介绍一下链剖分的概念(感谢laofu的讲课) 链剖分,是指一类 ...

  9. 【AC自动机】洛谷三道模板题

    [题目链接] https://www.luogu.org/problem/P3808 [题意] 给定n个模式串和1个文本串,求有多少个模式串在文本串里出现过. [题解] 不再介绍基础知识了,就是裸的模 ...

  10. 洛谷-P5357-【模板】AC自动机(二次加强版)

    题目传送门 -------------------------------------- 过年在家无聊补一下这周做的几道AC自动机的模板题 sol:AC自动机,还是要解决跳fail边产生的重复访问,但 ...

随机推荐

  1. BZOJ2069 POI2004ZAW(最短路)

    显然这样的路径一定是选择了与1相邻的不同的两点分别作为起点和终点(除1本身).如果能将每一组起点终点都计算到就可以得出最优解了.暴力显然不行.注意到我们每次求出的是单源最短路径,考虑如何充分利用信息. ...

  2. NOIP2014题解

    NOIP2014题解 Day1 生活大爆炸版石头剪刀布 rps 简单模拟题,注意细节 #include<iostream> #include<cstdio> using nam ...

  3. LOJ [#115. 无源汇有上下界可行流](https://loj.ac/problem/115)

    #115. 无源汇有上下界可行流 先扔个板子,上下界的东西一点点搞,写在奇怪的合集里面 Code: #include <cstdio> #include <cstring> # ...

  4. luogu1984 烧水问题 (找规律)

    为了节省能量,我们会希望一个已经烧开了的水温度越低越好 那么可以得到结论,它要依次去碰当前温度从大到小的水 然后再把温度最高的烧开呗 可是直接模拟会T 稍微写一写大概能找到每次烧开花费能量的一个规律 ...

  5. Linux:打印(输出)所有的列(awk, $0)

    如果想输出所有的列的话,只需要$0这个函数,例如以下命令: awk '/rs16945916/ {print $0}' test.txt > allcol.txt rs16945916指的是打印 ...

  6. Java 多线程间通信

    JDK 1.5 以后, 将同步和锁封装成了对象, 并将操作锁的隐式方法定义到了该对象中, 将隐式动作变成了显示动作. Lock 接口 Lock 接口, 位于 java.util.concurrent. ...

  7. 清除ul li里面的浮动并让ul自适应高度的一个好办法

    有时候会遇到ul li列表里面的东西会用到浮动,这个时候ul的高度就不会被撑开,这怎么办呢? 1)最笨的方法就是设置ul的高度,但这种方法很死板,高度不能自适应 2)有次我试着在ul里面加一个清除浮动 ...

  8. H3C配置FTP服务器

    H3C配置FTP服务器 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.FTP协议简介 1.FTP协议是互联网上广泛使用的文件传输协议 FTP文件传送协议(File Transf ...

  9. 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上 ...

  10. JAVA记录-redis缓存机制介绍(三)

    Redis 事务 Redis 事务可以一次执行多个命令, 并且带有以下两个重要的保证: 事务是一个单独的隔离操作:事务中的所有命令都会序列化.按顺序地执行.事务在执行的过程中,不会被其他客户端发送来的 ...