模板:Miller-RabinPollard-Rho(数论)

所谓 pollard-rho,就是泼辣的肉

(逃)

前言

许多题解都把这两个算法放在了一起。
那我也这样办吧!

miller-rabin可以在优秀的时间复杂度内完成对一个数的素性检测。
而pollard-rho则是立足于Miler-rabin之上,可以在 O(n14)O(n^\frac 1 4)O(n41) 的复杂度内分解出一个合数的非平凡因子。

Miller-rabin

费马定理:若 ppp 为质数,那么 ap≡a(modp)a^p\equiv a\pmod papa(modp),如果 a⊥pa\perp pap,同时也有 ap−1≡1(modp)a^{p-1}\equiv 1\pmod pap11(modp)

那么一个朴素的思想是随便找一个 aaa,看是否有 ap−1≡1(modp)a^{p-1}\equiv1\pmod pap11(modp)
但是,费马定理的逆定理并不成立,因此这个算法是很容易挂掉的,事实上,存在一类合数 nnn,对于任意的 a⊥na\perp nan,都有 ap−1≡1(modp)a^{p-1}\equiv1\pmod pap11(modp),这类数被称为卡迈克尔数。最小的卡迈克尔数为 561561561,已经可以证明,卡迈克尔数的数量是无穷个的。
我们需要更强的判断方法。

二次检测定理:如果 ppp 为质数,那么 x2≡1(modp)x^2\equiv1\pmod px21(modp) 的两个解分别为 x≡1(modp)x\equiv1\pmod px1(modp)x≡−1(modp)x\equiv-1\pmod px1(modp)

证明:移项得 (x+1)(x−1)≡0(modp)(x+1)(x-1)\equiv 0\pmod p(x+1)(x1)0(modp)由于 ppp 是质数,所以要使等式成立,只能是两个括号中的一个等于 000
反过来,如果对于一个 x≠±1(modp)x\ne\pm1\pmod px=±1(modp),出现了 x2≡1(modp)x^2\equiv 1\pmod px21(modp),那么 ppp 一定不是一个素数。

所以,我们考虑对于所有的奇素数 ppp222 可以特判),p−1p-1p1 都可以写成 a⋅2k(a%2=1,k>0)a\cdot 2^k(a\%2=1,k>0)a2k(a%2=1,k>0) 的形式,那么我们就可以把原来的式子变一下形:
xp−1≡1(modp)xa⋅2k≡1(modp)(xa⋅2k−1)2≡1(modp)x^{p-1}\equiv1\pmod p\\x^{a\cdot2^k}\equiv 1\pmod p\\(x^{a\cdot2^{k-1}})^2\equiv 1\pmod pxp11(modp)xa2k1(modp)(xa2k1)21(modp)
那么就出现了一个可以使用二次探测的形式,我们检查一下 xa⋅2k−1x^{a\cdot2^{k-1}}xa2k1 是否为 ±1\pm1±1 即可。同时,注意到,如果 k>1k>1k>1xa⋅2k−1x^{a\cdot2^{k-1}}xa2k1 依然等于 111,那么我们可以递归的进行多次二次探测。

虽然正确性大大提高,这个算法依然是一个概率性检测。我们需要多选取几个 aaa,多次检测才能尽可能的保证其正确性。
实践表明,选取前 121212 个质数已经可以保证 n=264n=2^{64}n=264 以内的正确性了。

注意! 费马定理的前提是 a⊥pa\perp pap,因此,如果 a=pa=pa=p,会把 ppp 错判成合数,需要特判。

int p[13]={0,2,3,5,7,11,13,17,19,23,29,31,37};
bool check(ll a,ll n){	ll k=n-1;if(ksm(a,k,n)!=1) return false;while(1){k>>=1;ll x=ksm(a,k,n);if(x!=1&&x!=n-1) return false;if(x==n-1||(k&1)) return true;}
}
bool prime(ll n){//miller-rabinif(n<3||((n&1)==0)) return n==2;for(int i=1;i<=12;i++){if(p[i]==n) return true;if(!check(p[i],n)) return false;}return true;
}

Pollard-Rho

感谢 _slb\text{\_slb}_slbAsta\text{Asta}Asta
(不会打红黑名凑活看吧)
既然弗洛伊德找环慢的一批,我就不浪费大家时间,直接讲倍增优化了。毕竟这两个算法前后也并不构成前置关系。(甚至感觉倍增更好理解一些

考虑一个随机数列:
xi≡xi−12+c(modp)x_i\equiv x_{i-1}^2+c\pmod pxixi12+c(modp)
其中 ccc 为一个随机常数。
这是一个很差的随机数实现,只要某一项出现相同,就会陷入循环节。
生日悖论告诉我们,它的循环节期望长度是 O(n)O(\sqrt n)O(n)
这个函数会在有限次后进入循环节,也就是:


这个样子(图源:oiwiki-分解质因数)

假设我们已经通过某种方式(比如 Miller-rabin) 知道了 nnn 是一个合数。
那么一定存在一个 mmm,满足 m∣n,m≤nm|n,m\le \sqrt nmn,mn
那么这个函数在 modm\bmod \space mmod m 的意义下的期望循环节长度就是 O(m)≤O(n14)O(\sqrt m)\le O(n^\frac 1 4)O(m)O(n41)

modn\bmod \space nmod n 意义下的环和 modm\bmod \space mmod m 意义下的小环是同时存在的,大概就长成这样:

请添加图片描述不难看出,这张图是我手画的。
其中黑线代表的是 modn\bmod\space nmod n 意义下的环(暂且叫它大环),红线是 modm\bmod \space mmod m 意义下的环(暂且叫它小环)。
那么我们要做的就是找到这个红线的环。
如何寻找?gcd⁡\gcdgcd
在函数上设置两个指针 sssttt,先让 ttt 不断的往后移(具体而言,就是令 t←f(t)t\gets f(t)tf(t))。然后计算 gcd⁡(∣t−s∣,n)\gcd(|t-s|,n)gcd(ts,n)。若 gcd⁡(∣s−t∣,n)>1\gcd(|s-t|,n)>1gcd(st,n)>1,说明找到了一个 nnn 的因子(或者说 s−ts-tst 恰好是一个 modm\bmod \space mmod m 意义下的环),就返回结果。

但是我们发现,如果 sssf(0)f(0)f(0) 点处待着不动弹,可能 ttt 怎么移动都没有用啊…
所以我们还需要时不时的把 sss 往前挪一挪。

还有一个问题:虽然我在这里把两个环叫做大环、小环,但是它们的大小关系只是在期望的意义下,也就是说,是有可能存在 modn\bmod\space nmod n 意义的环比 modm\bmod\space mmod m 的环要小的。
这个时候,两个指针还没绕完小环,就把大环绕完了。那么具体来说会出现什么情况?就是 ∣t−s∣≡0(modn)|t-s|\equiv0\pmod nts0(modn),这个时候 gcd⁡(0,n)\gcd(0,n)gcd(0,n) 会直接返回 nnn,那么这个时候我们就重新选择 ccc,重新跑就可以了。少侠请重新来过!

具体实现上,我们发现每次都求一遍 gcd⁡\gcdgcd 慢的一批,怎么办?我们可以把每次得到的 ∣s−t∣|s-t|st 都结果累乘再一起,隔一段时间一起算就可以啦!
累乘在一起太大了怎么办?没关系,伟大的欧几里德告诉我们: gcd⁡(a,n)=gcd⁡(amodn,n)\gcd(a,n)=\gcd(a\bmod n,n)gcd(a,n)=gcd(amodn,n),所以过程中取模就可以了。
那么我们具体要隔多长时间呢?间隔太短可能没啥效果,间隔太大可能明明早都出现了可以返回的结果,但你的代码还在傻傻的移动 ttt 指针,反而变得很慢。为了和倍增的实现更好的适应,我们最好选择形如 2k−12^k-12k1 的间隔,而事实是:间隔设为 127127127 口感最佳!

说了这么多,总于可以请出我们泼辣的肉的完整代码了!=v=

ll PR(ll n){//pollard-rhoc=rand()%(n-1)+1;ll s(0),t(0);ll val(1);for(int goal=1;;goal<<=1,s=t,val=1){//倍增for(int stp=1;stp<=goal;stp++){t=f(t,n);val=val*Abs(t-s)%n;if(stp%127==0){ll d=gcd(val,n);if(d>1) return d;}}ll d=gcd(val,n);if(d>1) return d;}
}
ll findfactor(ll x){ll p=x;while(p>=x) p=PR(x);//多次寻找return x;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/317119.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Asp.NetCore轻松学-部署到 Linux 进行托管

前言上一篇文章介绍了如何将开发好的 Asp.Net Core 应用程序部署到 IIS&#xff0c;且学习了进程内托管和进程外托管的区别&#xff1b;接下来就要说说应用 Asp.Net Core 的特性&#xff08;跨平台&#xff09;&#xff0c;将 .NetCore 部署到 Linux 中&#xff0c;主流的 Linu…

DevC++ 用C语言的多线程 实现简单的客户端和服务器

知识来源一&#xff1a; 使用Dev-C实现简单的客户端和服务器-CSDN博客 此先生的博客使用的是win32 SDK来创建多线程&#xff0c;然后鄙人对这个版本的多线程细节不明。于是又重新用C语言的线程替代win32API,以此继续学习服务器代码。 知识来源二&#xff1a;DevC 多线程创建…

[2021-09-09 T3] 序列/luogu P3943 星空(异或差分+bfs最短路+状压dp)

序列descriptionsolutioncodedescription 题目描述 长度为nnn的序列&#xff0c;初始全为000&#xff0c;每次可以选择⼀个数ai(1≤i≤l)a_i(1\le i\le l)ai​(1≤i≤l)&#xff0c;然后选择连续aia_iai​个元素异或上111 求最少的次数&#xff0c;使得对于所有i(1≤i≤k)i(…

HDU - 4608 I-number

题意&#xff1a; 给你一个x&#xff0c;让你构造一个y&#xff0c;y的要求&#xff1a; y>xy的各项之和为10的倍数在满足前两个的前提下&#xff0c;y尽可能小 题解&#xff1a; 模拟&#xff0c;尽可能的模拟&#xff0c;用字符串模拟 先将各位相加得到sum&#xff0c…

从初创公司的角度来看微服务

在开展微服务的过程中&#xff0c;了解要考虑哪些因素可能是非常有挑战性的事情。没有可以直接使用的金科玉律。每个过程都是不同的&#xff0c;因为每个组织面临的都是不同的环境。在本文中&#xff0c;我将从初创公司的角度分享我们学习到的经验和面临的挑战&#xff0c;以及…

洛谷P2056:[ZJOI2007]捉迷藏(点分树、STL)

解析 见到动态维护最远点对&#xff0c;不难想到利用 set 维护最大值和次大值&#xff0c;每个点维护两个 set 的杂技做法。 但是问题是…T了啊。 咋办嘞。 一个在本题至关重要的 trick&#xff1a;利用两个堆来支持访问最大值和删除 具体也很好理解&#xff1a;当删除的时候…

[NOI2018] 归程(线段树维护并查集的可持久化/kruskal重构树,倍增+dijkstra最短路)

[NOI2018] 归程descriptionsolution1code1solution2codedescription 题目描述 本题的故事发生在魔力之都&#xff0c;在这里我们将为你介绍一些必要的设定 魔力之都可以抽象成一个nnn个节点、mmm条边的无向连通图&#xff08;节点的编号从111至nnn&#xff09;我们依次用 l,…

CodeForces - 616D Longest k-Good Segment

CodeForces - 616D Longest k-Good Segment 题意&#xff1a; 有包含n个数的序列a&#xff0c;求能找到最长的区间包含不超过k个不同的元素。 题解&#xff1a; 尺取法&#xff0c;先固定L&#xff0c;然后移动R&#xff0c;R每次移动&#xff0c;当超过k后&#xff0c;L再…

MySQL 集群方案介绍

mysql集群方案这里介绍2种&#xff0c;PXC 和 Replication。大型互联网程序用户群体庞大&#xff0c;所以架构设计单节点数据库已经无法满足需求。大家也深有体会&#xff0c;有一万人在学校网站查成绩或是选课的时候网站时常是访问不了或者相应特别特别慢。这种情况就凸显出来…

模板:回文自动机(PAM)

所谓回文自动机&#xff0c;就是关于回文的自动机。 &#xff08;逃&#xff09; 前言 小清新自动机。 经历过SAM的大风大浪&#xff0c;这个相比而言好理解多了&#xff0c;感觉也许应该先学这个再学SAM… 解析 和trie、AC自动机、SAM等类似的&#xff0c;PAM的每个结点表…

Gym - 215177C 玩游戏

题意&#xff1a; ljcc和他的学妹在玩游戏&#xff0c;这个游戏共有 n 轮&#xff0c;在第 i 轮获胜会获得 i 分&#xff0c;没有平局。 现在给出ljcc和学妹的得分&#xff0c;求是否有一种方案符合当前得分。 题解&#xff1a; 第i轮得到i分&#xff0c;一共n轮&#xff0…

Zju2112 Dynamic Rankings(树状数组套可持久化权值线段树)

Zju2112 Dynamic Rankingsdescriptionsolutioncodedescription 给定一个含有n个数的序列a[1],a[2],a[3]……a[n]&#xff0c;程序必须回答这样的询问&#xff1a;对于给定的i,j,k&#xff0c;在a[i],a[i1 ],a[i2]……a[j]中第k小的数是多少(1≤k≤j-i1)&#xff0c;并且&…

ML.NET案例详解:在.NET下使用机器学习API实现化学分子式数据格式的判定

半年前写过一篇类似的文章&#xff0c;题目是&#xff1a;《在.NET中使用机器学习API&#xff08;ML.NET&#xff09;实现化学分子式数据格式的判定》&#xff0c;在该文中&#xff0c;我介绍了化学分子式数据格式的基本知识&#xff0c;同时给出了一个案例&#xff0c;展示了如…

洛谷P4762: [CERC2014]Virus synthesis(PAM)

解析 自己对PAM的理解不够深刻。 最优方案必然是先选择一个偶回文串&#xff0c;递归构造出它的一半。花一步逆序&#xff0c;然后暴力解决剩下的。 这似乎已经依稀出现了某种dp的思路。 考虑如何更好的转移。设计 transxtrans_xtransx​ 表示长度不超过 xxx 一半的最长回文后…

Triangle HDU - 5914

Triangle HDU - 5914 题意&#xff1a; 有长度分别是1到n的n给木棍&#xff0c;问最少拿走几个木棍&#xff0c;使得剩下木棍无法组成三角形 题解&#xff1a; 组不成三角形的恰巧情况就是ab<c&#xff0c;也就是我们要让剩下的木棍&#xff0c;两者之和等于或小于第三个…

CodeForces - 336A Vasily the Bear and Triangle

CodeForces - 336A Vasily the Bear and Triangle 题意&#xff1a; 给你一个点x&#xff0c;现在这个点和原点组成了矩形&#xff0c;让你在x和y轴分别求一个点&#xff0c;与原点构成的三角形&#xff0c;要求矩形在三角形内&#xff0c;点x在斜边上 题解&#xff1a; 这…

数据结构之线段树合并——永无乡,Lomsat gelral,Tree Rotations,Tree Rotations Escape Through Leaf

文章目录[HNOI2012]永无乡Lomsat gelral「POI2011 R2 Day2」旋转树木 Tree RotationsEscape Through Leaf线段树合并与 fhq-treap合并很类似&#xff0c;也是将两个不同根的线段树暴力合并至于时间复杂度&#xff0c;线段树合并一次是可以达到O(n)O(n)O(n)的&#xff0c;但是大…

吉特仓储管理系统--开源2018年源码

应该说今天过完&#xff0c;这个年就算真正意义上的过完了&#xff0c;没有想到的是又是在出差的路上写这样的文章。废话也不多说&#xff0c;写这篇文章主要的目的是想将去年吉特仓储管理系统开发的一个版本源代码开放出来&#xff0c;供各位开发者阅读使用。github 源代码地址…

模板:广义SAM(字符串)

所谓广义SAM&#xff0c;就是更广泛意义下的SAM &#xff08;逃&#xff09; 前言 感觉字符串的理解难度的巅峰还是在SAM&#xff0c;广义SAM只是在套一些特判罢了&#xff0c;并不是太难理解。 可以解决多字符串的子串问题&#xff0c;几乎就是把SAM能做的东西从单串变成了多…

自定义Visual Studio.net Extensions 开发符合ABP vnext框架代码生成插件[附源码]

介绍我很早之前一直在做mvc5 scaffolder的开发功能做的已经非常完善,使用代码对mvc5的项目开发效率确实能成倍的提高,就算是刚进团队的新成员也能很快上手,如果你感兴趣 可以参考 http://neozhu.github.io/MVC5-Scaffolder/#/ https://github.com/neozhu/MVC5-Scaffolder但是m…