正题

题目链接:https://www.luogu.com.cn/problem/P4718


题目大意

给出一个数nnn,如果它是质数则输出PrimePrimePrime,否则输出它的最大质因子。


解题思路

Pollard-Rho\text{Pollard-Rho}Pollard-Rho算法的前置知识是Miller-Rabin\text{Miller-Rabin}Miller-Rabin。在使用Miller-Rabin\text{Miller-Rabin}Miller-Rabin判掉质数之后,Pollard-Rho\text{Pollard-Rho}Pollard-Rho使用基于随机的思想能够较快的求出一个大数的因子之一。

朴素的随机算法就是随机一个数判断它是不是因子,我们先使用一个较为优秀的随机方式,f(x)=f(x−1)2+cf(x)=f(x-1)^2+cf(x)=f(x−1)2+c(其中ccc为一个常数)。

然后我们利用在这个函数上“跑”的距离来判断,也就是每次拿某两个i,ji,ji,j,判断∣f(i)−f(j)∣|f(i)-f(j)|∣f(i)−f(j)∣是否为它的因数。

但是如果枚举的话fff函数上会出现一些“环”,我们需要快速的判掉“环”的方法。每次拿s,ts,ts,t,令t=2st=2st=2s,若环长为ccc,那么有f(x)=f(x+c)f(x)=f(x+c)f(x)=f(x+c),当某一时刻f(t)=f(s)f(t)=f(s)f(t)=f(s)那么环长一定是sss的整数倍。

然后判到环就退出,如果没有找到就换一个常数重新做,这样的我们的算法雏形就形成了。

但是这样还是跑的很慢,发现我们在过程中大量调用了gcd(d,p)gcd(d,p)gcd(d,p)导致时间变慢。考虑优化,我们可以每次先做一堆,然后在把这一堆拿过去一起搞定。首先我们有gcd(ac,b)=gcd(a,b)gcd(ac,b)=gcd(a,b)gcd(ac,b)=gcd(a,b),然后根据gcdgcdgcd的原理,我们有gcd(a,b)=gcd(a%b,b)gcd(a,b)=gcd(a\% b,b)gcd(a,b)=gcd(a%b,b)那么也就是我们有gcd(a,b)=gcd(ac%b,b)gcd(a,b)=gcd(ac\%b,b)gcd(a,b)=gcd(ac%b,b)。

那么假设我们有若干个间隔a1,a2,a3,...a_1,a_2,a_3,...a1​,a2​,a3​,...那么我们把这数乘起来模ppp,然后把得到的结果kkk与ppp取gcdgcdgcd就等价于拿aaa中逐个取与ppp取gcdgcdgcd。

所以我们的优化方法就是第iii次拿2i2^i2i个间隔去一起与ppp判断,但是因为iii后面会很大导致副作用,所以将iii设一个上界888即可。
时间复杂度期望是O(n2.5)O(n^{2.5})O(n2.5),但跑的飞快

回到这题来,我们先对nnn用MR\text{MR}MR判断一次质数,然后跑Pr\text{Pr}Pr弄出一个因子ddd,之后将nnn的因子ddd都去光后分别把nnn和ddd丢下去递归继续跑。可以记录一个目前最大质因子来剪去一些不优状态。


codecodecode

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#define ll long long
using namespace std;
const ll pri[10]={2,3,5,7,11,13,17,19,23,27};
ll T,n,ans;
ll ksc(ll a,ll b,ll p){ll c=(long double)a*b/p;long double ans=a*b-c*p;if(ans<0)ans+=p;else if(ans>=p)ans-=p;return ans;
}
ll power(ll x,ll b,ll p){ll ans=1;while(b){if(b&1)ans=ksc(ans,x,p);x=ksc(x,x,p);b>>=1;}return ans;
}
bool Mr(ll p){if(p==2)return 1;if(p<2||!(p&1))return 0;ll t=p-1,s=0;while(!(t&1))t>>=1,s++;for(ll i=0;i<10&&pri[i]<p;i++){ll x=power(pri[i],t,p),k;for(ll j=0;j<s;j++){k=ksc(x,x,p);if(k==1&&x!=1&&x!=p-1)return 0;x=k;}if(x!=1)return 0;}return 1;
}
ll gcd(ll a,ll b)
{return (!b)?a:gcd(b,a%b);}
ll Pr(ll p){ll s=0,t=0,c=1ll*rand()%(p-1)+1;for(ll g=1,val=1,d;;g<<=1,s=t,val=1){for(ll j=0;j<g;j++){t=(ksc(t,t,p)+c)%p;val=ksc(val,abs(t-s),p);if(j%127==0&&(d=gcd(p,val))>1)return d;}d=gcd(p,val);if(d>1)return d;}return p;
}
void solve(ll n){if(n<ans||n<2)return;if(Mr(n)){ans=n;return;}ll d=0;while((d=Pr(n))>=n);while(n%d==0)n/=d;solve(n);solve(d);return;
}
signed main()
{srand(998244353);scanf("%lld",&T);while(T--){scanf("%lld",&n);if(Mr(n)){printf("Prime\n");continue;}ans=0;solve(n);printf("%lld\n",ans);}return 0;
}

P4718-[模板]Pollard-Rho算法相关推荐

  1. 大整数分解——Pollard Rho算法

    延续上一篇,这次来讲一讲大整数分解算法的应用. 要解决的问题很简单,对一个整数进行分解质因数. 首先还是效率非常低的暴力算法,相信大家都会,不多提. 和上次一样,当数达到非常大的时候,分解将变得非常困 ...

  2. c语言用rho函数求复数模长,Pollard Rho 算法简介

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

  3. BZOJ 5330 Luogu P4607 [SDOI2018]反回文串 (莫比乌斯反演、Pollard Rho算法)

    题目链接 (BZOJ) https://www.lydsy.com/JudgeOnline/problem.php?id=5330 (Luogu) https://www.luogu.org/prob ...

  4. 因数分解 Pollard rho

    因数分解 Pollard rho 算法思路 随机生成两个数a,ba,ba,b,然后求gcd⁡(n,a−b)\gcd\pod{n,a-b}gcd(n,a−b),如果其值不为111,则这个数就是nnn的一 ...

  5. 素数判定质因数分解(数论)(Miller Rabin)(Pollard Rho)

    太玄学了! 我真的被概率的魅力折服了.此前我认为1便是1,0.9999999999-便是0.9999999999-. 但实际上它们有着千丝万缕的关系. 试想,如果一件事发生的概率是0.99999999 ...

  6. 洛谷P4718 【模板】Pollard-Rho算法

    虽然很久以前就听说过PR算法,但前几天第一次打. 首先miller rabin判断素数,不在复杂度瓶颈. pollard rho倍增环长,复杂度是\(O(n^{\frac{1}{4}} log n)\ ...

  7. 【快速因数分解】Pollard's Rho 算法

    算法目的 给一个数n,快速提取n的一个因数. 算法根据:生日悖论 讲生日悖论之前,先看一个东西. 给出[1-1000]的数,从中任意选出一个数为k的概率是110001\over 100010001​. ...

  8. 64位以内Rabin-Miller 强伪素数测试和Pollard rho 因数分解解析

    在求解POJ1811题Prime Test中应用到的两个重要算法是Rabin-Miller强伪素数测试和Pollard r因数分解算法.前者可以在的时间内以很高的成功概率判断一个整数是否是素数.后者可 ...

  9. 我的所有优质博客全部开源啦(我自己原创的《ACM模板》《算法全家桶》《算法竞赛中的初等数论》 PDF免费下载)

    你好呀ヾ(≧▽≦*)o 我是繁凡さん 这两年来我写了很多长篇文章,主要涉及数据结构,算法,程序设计竞赛,数学,计算几何等方面的内容: <数据结构>C语言版(清华严蔚敏考研版) 全书知识梳理 ...

  10. 整数的素因子分解:Pollard rho method

    参考: 1.CLRS<算法导论> 2.http://www.csh.rit.edu/~pat/math/quickies/rho/#algorithm Pollard rho方法是随机算法 ...

最新文章

  1. 利用webpack和vue实现组件化
  2. ImportBeanDefinitionRegistrar向容器中注册bean
  3. 你很可能需要知道这个调试小技巧
  4. Android Activity中状态保存机制
  5. 如何用c++画图_画图教室 | 绘制Mapping第一步:美团搜索火锅串串香...认真的!...
  6. 案例-翻转的导航栏(CSS3)
  7. n皇后---一维数组解法
  8. 如何在Mac视频中删除音频呢?
  9. AVPlayer 音视频缓存方案
  10. JavaScript网页特效5则
  11. 计算机虚拟仿真专业,计算机虚拟仿真实验教学中心
  12. cad如何多选对象_cad中选择对象,不小心多选了一条线,怎么取消这个多选的家伙...
  13. 一个产品的风险预测怎么写_创业计划书中,项目风险评估怎么写?
  14. 蘑菇街服务器信息,蘑菇街开放平台
  15. IOS APP的图标尺寸、启动画面尺寸、宣传画面尺寸
  16. CCNA-思科网络基础(IP地址 MAC地址 DNS DHCP PING )
  17. 美团移动端主页+订单界面
  18. CPU(AMD)2020.10购买推荐
  19. 主机宝iis版_主机宝IIS版|IIS网站宝(IIS科技主机管理系统)下载 v3.0 官方免费版 - 比克尔下载...
  20. 麦克风阵列杂音很重解决方案(科大讯飞麦克风阵列+6.0)

热门文章

  1. linux脚本多线程,Shell多线程操作及线程数控制实例
  2. 根据url获取html源码,通过URL访问和获取html源代码
  3. java得到文件创建时间linux,linux java获取文件创建时间
  4. php5.2 zengd,大对杀狗狗再犯低级错误 ZEN狂输200目笑翻棋友
  5. python反射、闭包、装饰器_python之闭包、装饰器、生成器、反射
  6. python base64编码_JS和Python实现AES算法
  7. 调整png的不透明度_TGA与PNG的优劣对比
  8. matlab仿真习题,(MATlab仿真部分习题答案.doc
  9. 算法题目中经典问题(易错点)
  10. libgo 支持mysql,loadrunner通过使用libmysql.dll完成mysql的测试-Go语言中文社区