前言:

在观看此博客之前请学习miller_rabin。

我们在分解质因子时也许只会用试根法(也就是暴力)。

而在此我们将学习一个玄学的算法——Pollard_rho。

概念:

Pollard_rho是一种基于随机的算法,它的思路是先用miller_rabin来判断当前数是否已经是素数了,如果是的话记录并返回。如果不是,我们设要分解的数为n,那么我们考虑去找一个当前数的因数p,找到之后再分别对p和n/p分解质因数,有一点类似分治但是不是分治。

算法如图:

那么,我们要如何快速地找到当前数的因数呢?

这里,我们采用以下方法:先随机生成两个1~n的数,利用这两个数差的绝对值和n比较,来判断这两个数差的绝对值是不是n的一个因数。

可这又是为什么?

那么我们就要讲到一个叫生日悖论的东西了。

这里又出现了一个问题:我们为什么要使用两个随机数差的绝对值来判断是否为n的因数之一,而不是直接生成一个随机数来进行判断呢?

这里我们来讲一下生日悖论:

生日悖论,指如果一个房间里有23个或23个以上的人,那么至少有两个人的生日相同的概率要大于50%。这就意味着在一个典型的标准小学班级(30人)中,存在两人生日相同的可能性更高。对于60或者更多的人,这种概率要大于99%。

如何计算:

第一个人的生日是 365选365

第二个人的生日是 365选364

第三个人的生日是 365选363

第n个人的生日是 365选365-(n-1)

那么,所有人的生日都不同的概率为:

所有人中,至少有两个人生日相同的概率为:

当n=23时,这个概率为0.507,n=100时,概率为0.999999692751072。

当然,选取两个数也是有道理的。

一开始,我们先随机生成两个数x和c,每次都使x=x*x+c(mod n) ,另外再设置一个数y,y的初始值为x,每进行2^k次操作,就让y记为现在的x。在计算的过程中,我们可以发现x=x*x+c(mod n)这个过程是会出现循环的,具体图像会像希腊字母ρ(rho)一旦出现循环我们还没有找到可以分解的因数,就意味着这次随机失败了,需要我们再次进行随机。我们为了记录什么时候出现了循环,我们每个2^k次计算就把y记录成现在的x,如果在接下来的2^k次操作中,出现了y=x,就意味着出现了循环。所以,y的作用一是为了当随机的第二个数,二是为了判断循环。

代码如图:

ll Pollard_rho(ll n1,ll c)//ll 为long long
{ll i=1,k=2;ll x=rand()%n1;ll y=x;while(1){i++;x=(qkch(x,x,n1)+c)%n1;ll d=gcd(y-x,n1);if(d>1&&d<n)return d;if(x==y)return n1;if(i==k){y=x;k=k*2;}}
}

题目描述:

Given a big integer number, you are required to find out whether it's a prime number.

输入:

The first line contains the number of test cases T (1 <= T <= 20 ), then the following T lines each contains an integer number N (2 <= N < 2 54).

输出:

For each test case, if N is a prime number, output a line containing the word "Prime", otherwise, output a line containing the smallest prime factor of N.

样例输入:

2
5
10

样例输出:

Prime
2

此题为模板题就不需多讲。

代码实现:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<ctime>
#define INF 1ll << 60
using namespace std;
#define ll long long
ll n,ans,t;
ll qkch(ll x,ll y,ll mod)
{ll res=0;while(y){if(y&1)res=(res+x)%mod;x=(x*2)%mod;y/=2;}return res;
}
ll gcd(ll a,ll b)
{if(a==0)return 1;if(a<0)return gcd(-a,b);while(b>0){ll t=a%b;a=b;b=t;}return a;
}
ll qkpow(ll x,ll y,ll mod)
{ll ans=1;while(y){if(y&1)ans=qkch(ans,x,mod);x=qkch(x,x,mod);y/=2;}return ans;
}
bool miller_robin(ll n1)
{if(n1==2)return 1;if(n1<2||!(n1&1))return 0;ll x,u,pre;ll k=0;u=n1-1;while(!(u&1)){k++;u>>=1;}for(int i=1;i<=3;i++){x=rand()%(n1-1)+1;x=qkpow(x,u,n1);pre=x;for(int j=1;j<=k;j++){x=qkch(x,x,n1);if(x==1&&pre!=n1-1&&pre!=1)return 0;pre=x;}if(x!=1)return 0;}return 1;
}
ll Pollard_rho(ll n1,ll c)
{ll i=1,k=2;ll x=rand()%n1;ll y=x;while(1){i++;x=(qkch(x,x,n1)+c)%n1;ll d=gcd(y-x,n1);if(d>1&&d<n)return d;if(x==y)return n1;if(i==k){y=x;k=k*2;}}
}
void findit(ll p)
{if(miller_robin(p)==1){if (ans>p)ans=p;return;}ll p1=p;while(p1>=p){p1=Pollard_rho(p1,rand()%(p-1)+1);//printf("%lld %lld\n",p,p1);}findit(p1);findit(p/p1);
}
int main()
{srand(time(0));scanf("%lld",&t);while(t--){ans=INF;scanf("%lld",&n);if(miller_robin(n))printf("Prime\n");else{findit(n);printf("%lld\n",ans);}}
}

C++Pollard_rho分解质因数及其例题—————Prime Test相关推荐

  1. 信奥中的数学基础:分解质因数

    五分钟掌握一个小学数学知识点--分解质因数(苏教版五年级下册) 五分钟掌握一个小学数学知识点--分解质因数(苏教版五年级下册)_哔哩哔哩_bilibili [算法竞赛中的数学]素数筛选与质因数分解 [ ...

  2. [玄学]——数论高级之分解质因数(Pollard_rho)(POJ 1811)

    前言 这是一个伤心的故事:我已经好久没有写博客了... 当然这次跟大家分享的是一个很玄学的东西--Pollard_rho 为什么说他很玄学呢?大家可以在等下的代码中看出来(全是rand...) 当然, ...

  3. codeforces-26A-Almost Prime【分解质因数】

    codeforces-26A-Almost Prime[分解质因数] time limit per test2 seconds memory limit per test256 megabytes A ...

  4. 分解质因数-Pollard‘s Rho

    Pollard's Rho 质数的判定 试除法 Fermat 素性测试 Miller-Rabin 素性测试 查找因数 还是试除法 Pollard's Rho 分解质因数   随便写写,不喜勿喷. 质数 ...

  5. 阶乘分解质因数[经典题组合数学枚举质因子]

    引入问题: 给定整数NNN,试把阶乘 N!N!N! 分解质因数,按照算术基本定理的形式输出分解结果中的 pip_ipi​ 和 cic_ici​即可. N!N!N!分解质因数后的结果,共若干行,每行一对 ...

  6. 算法刷题-数论-质数的判定、分解质因数、筛质数

    文章目录 数论 1. 质数 质数的判定---试除法 分解质因数---试除法 筛质数 朴素筛法 埃氏筛法 线性筛法 数论 1. 质数 质数:在大于1的整数中,如果只包含1和它本身这两个约数,那么这个数就 ...

  7. 【分解质因数】【树状数组】【快速幂】codeforces 2014 ACM-ICPC Vietnam National Second Round E. ACM...

    乘除都在150以内,分解质因数后发现只有35个,建立35个树状数组/线段树,做区间加.区间查询,最后快速幂起来. #include<cstdio> #include<cstring& ...

  8. 翁恺c语言第6周编程答案,程序设计入门——C语言 第6周编程练习 1 分解质因数(5分)(示例代码)...

    1 分解质因数(5分) 题目内容: 每个非素数(合数)都可以写成几个素数(也可称为质数)相乘的形式,这几个素数就都叫做这个合数的质因数.比如,6可以被分解为2x3,而24可以被分解为2x2x2x3. ...

  9. 分解质因数-洛谷P3200 [HNOI2009]有趣的数列

    https://www.luogu.org/problem/show?pid=3200 首先,我们不能保证要求的数的逆元和模域互质: 所以我们要用分解质因数来抵消除法: 其实逆元的话即使可行也会超时: ...

  10. 信息学奥赛一本通 2032:【例4.18】分解质因数

    [题目链接] ybt 2032:[例4.18]分解质因数 [题目考点] 1. 质数 [解题思路] 解法1:使用循环 每次循环中,遍历2到n,找到一个n的质因数,输出,而后n除以该因数,继续循环. 解法 ...

最新文章

  1. 【实战分享】安卓app测试的一些记录
  2. 文字图片垂直居中对齐
  3. CAN接口芯片SN65HVD230DR波形
  4. (三)协同过滤算法之基于物品的推荐算法python实现
  5. ubuntu下面的报错Call to undefined function curl_init()
  6. Python开发中收集的一些常用功能Demo
  7. 零基础也能学会的小游戏编程!入门级别实践
  8. 60页论文综述深度学习优化方法,出自UIUC
  9. vbox 中ubuntu20.04和宿主机共享文件_如何在家搭建一套自己的实验平台(10)iSCSI 共享存储...
  10. 2021年上半年网络工程师上午真题及答案解析
  11. 新高考成绩分析教师增值评价系统1:新高考等级赋分转换
  12. linux 配置软件安装源
  13. html中文网页设计作品
  14. opensim源码安装教程
  15. win10专业版激活
  16. Java 八皇后游戏
  17. 计算机算法在生物信息学中的应用,引力场算法及其在生物信息学中的应用
  18. 2019 掘安杯 JACTF MISC WP
  19. 鞘氨醇-1-磷酸的生物学作用
  20. 思考14. 为什么我们要全力以赴

热门文章

  1. 开放阿里云指定端口及设置本地代理访问自己的阿里云服务器
  2. 电脑系统服务器丢失怎么办,电脑本地连接不见了,小编教你怎么解决
  3. Unity - Timeline 之 Timeline Setting(Timeline的设置)
  4. 全球行业品牌“中国制冷展”将亮相汉渝 寻觅发展新空间
  5. (六)我的JavaScript系列:更好的JavaScript之CoffeeScript
  6. python设置颜色深浅_海伯恩例外,因为颜色深浅
  7. 删除服务器tomcat上项目,删除tomcat服务器
  8. 做为软件测试的前辈,你能不能给我一点建议?
  9. 最新电脑cpu性能排行服务器,服务器cpu性能排行,手把手教你服务器cpu性能排行...
  10. JavaScript格式化字符串为指定长度