BZOJ_3667_Rabin-Miller算法_Mille_Rabin+Pollard rho

Description

Input

第一行:CAS,代表数据组数(不大于350),以下CAS行,每行一个数字,保证在64位长整形范围内,并且没有负数。你需要对于每个数字:第一,检验是否是质数,是质数就输出Prime
第二,如果不是质数,输出它最大的质因子是哪个。

Output

第一行CAS(CAS<=350,代表测试数据的组数)
以下CAS行:每行一个数字,保证是在64位长整形范围内的正数。
对于每组测试数据:输出Prime,代表它是质数,或者输出它最大的质因子,代表它是和数

Sample Input

6
2
13
134
8897
1234567654321
1000000000000

Sample Output

Prime
Prime
67
41
4649
5

HINT

数据范围:

保证cas<=350,保证所有数字均在64位长整形范围内。


思路就是分解出一个因数,然后递归下去,直到这个数为质数,取最大的输出即可。


那么首先有判断质数的方法Miller_Rabin:

根据费马小定理,$a^{p-1}mod{p}=1$,$p$为质数。

以及$x^2mod{p}=1$,$p$为质数的解只有$1$和$p-1$。

这两个同时满足且$p$不是质数的概率就很低了,我们还可以多试几次。

具体地,把$n-1$分解成$a^r*2^s$的形式,然后用$a^r$一直平方,同时验证这两个。


然后有基于生日悖论的快速求约数的方法Pollard rho:

选取$0~n-1$的几个数,用连续的两个数$x,y$求$gcd(x-y,n)$,如果这不等于$1$则找到了一个$n$的约数。

其中$x$和$y$可以用某个函数生成,比如说$f(x)=x^2+c$,但这样可能进到一个环里找不到约数。

这时我们跳出来对$c$进行随机赋值就可以。

如何跳出来?可以让$x$一次跑一步$(x=f(x))$,让$y$一次跑两步$(y=f(f(y)))$,这样如果$x=y$就跳出即可。

(有一个bug:当$n=4$时会一直进去,$Abs(x-y)$永远不会等于$2$)

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdlib>
using namespace std;
typedef double f2;
typedef long long ll;
ll ch(ll a,ll b,ll mod) {ll d=(ll)floor(1.0*a/mod*b+0.5),re=a*b-d*mod; return re<0?re+mod:re;}
ll qp(ll x,ll y,ll mod) {ll re=1;for(;y;y>>=1ll,x=ch(x,x,mod)) if(y&1ll) re=ch(re,x,mod); return re;}
ll gcd(ll x,ll y) {return y?gcd(y,x%y):x;}
ll random(ll x,ll y) {
return ((rand()*(1ll<<45))+(rand()<<30)+(rand()<<15)+(rand()))%(y-x+1)+x;
}
ll Abs(ll x) {return x>0?x:-x;}
ll maxn,a[]={2,3,5,7,11,13,17,19,23,29};
bool check(ll a,ll n,ll r,ll s) {
ll x=qp(a,r,n),y=x,i;
for(i=1;i<=s;i++,y=x) {x=ch(x,x,n); if(x==1&&y!=1&&y!=n-1) return 0;}
return x==1;
}
bool MR(ll n) {
if(n<=1) return 0; ll r=n-1,s=0,i;
for(;!(r&1);r>>=1ll,s++);
for(i=0;i<9;i++) {
if(a[i]==n) return 1;
if(!check(a[i],n,r,s)) return 0;
}
return 1;
}
ll f(ll x,ll c,ll mod) {return (ch(x,x,mod)+c)%mod;}
ll PR(ll n,ll c) {
ll x=random(0,n-1),y=x,p;
for(p=1;p==1;) {
x=f(x,c,n); y=f(f(y,c,n),c,n); p=gcd(Abs(x-y),n);
}
return p;
}
void solve(ll n) {
if(n<=1) return ; if(MR(n)) {maxn=max(maxn,n); return ;}
if(n%2==0) {
while(n%2==0) n/=2;
solve(n); maxn=max(maxn,2ll); return ;
}
ll tmp=n; while(tmp==n) tmp=PR(n,random(0,n-2));
solve(tmp); solve(n/tmp);
}
int main() {
srand(19260817); rand();
int T; scanf("%d",&T);
while(T--) {
ll n; scanf("%lld",&n);
maxn=0; solve(n);
if(n==maxn) printf("Prime\n");
else printf("%lld\n",maxn);
}
}

BZOJ_3667_Rabin-Miller算法_Mille_Rabin+Pollard rho的更多相关文章

  1. Pollard Rho 算法简介

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

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

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

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

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

  4. Pollard Rho算法浅谈

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

  5. 初学Pollard Rho算法

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

  6. Miller-Rabin 素性测试 与 Pollard Rho 大整数分解

    \(\\\) Miller-Rabin 素性测试 考虑如何检验一个数字是否为素数. 经典的试除法复杂度 \(O(\sqrt N)\) 适用于询问 \(N\le 10^{16}\) 的时候. 如果我们要 ...

  7. 浅谈 Miller-Robbin 与 Pollard Rho

    前言 $Miller-Robbin$ 与 $Pollard Rho$ 虽然都是随机算法,不过用起来是真的爽. $Miller Rabin$ 算法是一种高效的质数判断方法.虽然是一种不确定的质数判断法, ...

  8. 整数(质因子)分解(Pollard rho大整数分解)

    整数分解,又称质因子分解.在数学中,整数分解问题是指:给出一个正整数,将其写成几个素数的乘积的形式. (每个合数都可以写成几个质数相乘的形式,这几个质数就都叫做这个合数的质因数.) .试除法(适用于范 ...

  9. Pollard Rho因子分解算法

    有一类问题,要求我们将一个正整数x,分解为两个非平凡因子(平凡因子为1与x)的乘积x=ab. 显然我们需要先检测x是否为素数(如果是素数将无解),可以使用Miller-Rabin算法来进行测试. Po ...

随机推荐

  1. 集训第六周 数学概念与方法 数论 筛素数 H题

    Description 小明对数的研究比较热爱,一谈到数,脑子里就涌现出好多数的问题,今天,小明想考考你对素数的认识.  问题是这样的:一个十进制数,如果是素数,而且它的各位数字和也是素数,则称之为“ ...

  2. Python基础—线程、进程和协程

    今天已是学习Python的第十一天,来干一碗鸡汤继续今天的内容,今天的鸡汤是:超越别人对你的期望.本篇博客主要介绍以下几点内容: 线程的基本使用: 线程的锁机制: 生产者消费之模型(队列): 如何自定 ...

  3. CodeForcesGym 100517H Hentium Scheduling

    Hentium Scheduling Time Limit: 2000ms Memory Limit: 262144KB This problem will be judged on CodeForc ...

  4. Android渲染器Shader:LinearGradient(一)

     Android渲染器Shader:LinearGradient(一) LinearGradient是Android的线性渲染器.我写5个LinearGradient渲染器渲染后的View表现结果 ...

  5. POJ-1679 The Unique MST,次小生成树模板题

    The Unique MST Time Limit: 1000MS   Memory Limit: 10000K       Description Given a connected undirec ...

  6. Spark 静态内存管理

    作者编辑:杜晓蝶,王玮,任泽 Spark 静态内存管理详解 一. 内容简介 spark从1.6开始引入了动态内存管理模式,即执行内存和存储内存之间可以互相抢占.spark提供两种内存分配模式,即:静态 ...

  7. 開啟活動監視器 (SQL Server Management Studio)

    本主題描述如何開啟 [活動監視器] 來取得有關 SQL Server 處理序以及這些處理序如何影響目前 SQL Server 執行個體的資訊. 此外,本主題也描述如何設定 [活動監視器] 的重新整理間 ...

  8. HDU1241&POJ2386 dfs简单题

    2道题目都差不多,就是问和相邻所有点都有相同数据相连的作为一个联通快,问有多少个连通块 因为最近对搜索题目很是畏惧,总是需要看别人代码才能上手,就先拿这两道简单的dfs题目来练练手,顺便理一理dfs的 ...

  9. bzoj 3173 [Tjoi2013]最长上升子序列 (treap模拟+lis)

    [Tjoi2013]最长上升子序列 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2213  Solved: 1119[Submit][Status] ...

  10. Jquery根据JSON生成Table

    先说下背景 本人属于juqery小白中的极品小白.基本对于JS jquery这些不懂.用到时候基本百度下 拿过来改改OK. 上面这东西让我弄了三天.可能对于其他人来说 一天就搞定了 .看来还真得去学一 ...