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

BZOJ 3667: Rabin-Miller算法

Time Limit: 60 Sec  Memory Limit: 512 MB
Submit: 1044  Solved: 322
[Submit][Status][Discuss]

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算法,不过真正上也需要Pollard rho算法

  1 /*貌似这个代码在BZOJ上的评测器就会运行错误,但是在POJ上一道原题却通过了(POJ上语言选C++可以过,选择G++就过不了)*/
  2 #include<iostream>
  3 using namespace std;
  4 #include<cstdio>
  5 #define S 10
  6 #include<cstdlib>
  7 #include<ctime>
  8 #define ll long long
  9 ll cas, maxz=-1;
 10 ll read()
 11 {
 12     ll ans=0;char c;
 13     c=getchar();
 14     while(c<‘0‘||c>‘9‘) c=getchar();
 15     while(c>=‘0‘&&c<=‘9‘)
 16     {
 17         ans=ans*10+c-‘0‘;
 18         c=getchar();
 19     }
 20     return ans;
 21 }
 22 ll quick_mul_mod(ll a,ll b,ll c)//a*b%c
 23 {
 24     ll ret=0;
 25     a%=c;b%=c;
 26     while(b)
 27     {
 28         if(b&1)
 29         {
 30             ret+=a;
 31             ret%=c;
 32             b--;
 33         }
 34         a<<=1;
 35         a%=c;
 36         b>>=1;
 37     }
 38     return ret;
 39 }
 40 ll gcd(ll a,ll b)
 41 {
 42     if(a==0) return 1;
 43     if(a<0) return gcd(-a,b);
 44     if(b==0)
 45     return a;
 46     return gcd(b,a%b);
 47 }
 48 ll Pollard_rho(ll x,ll c)
 49 {
 50     ll x1=rand()%(x-1)+1;
 51     ll x2=x1;
 52     int i=1,k=2;
 53     while(1)
 54     {
 55         i++;
 56         x1=(quick_mul_mod(x1,x1,x)+c)%x;
 57         ll d=gcd(x2-x1,x);
 58         if(d!=1&&d!=x) return d;
 59         if(x2==x1) return x;
 60         if(i==k)
 61         {
 62             x2=x1;
 63             k+=k;
 64         }
 65     }
 66
 67 }
 68 ll quick_mod(ll a,ll b,ll c)//ji suan a^b%c
 69 {
 70     ll ans=1;
 71     a%=c;
 72     while(b)
 73     {
 74         if(b&1)
 75         {
 76             b--;
 77             ans=quick_mul_mod(ans,a,c);
 78         }
 79         b>>=1;
 80         a=quick_mul_mod(a,a,c);
 81     }
 82     return ans;
 83 }
 84 bool Miller_rabin(ll n)
 85 {
 86     if(n==2) return true;
 87     if(n<=1||!(n&1)) return false;
 88     ll u=n-1,t=0;
 89     while(!(u&1))
 90     {
 91         u>>=1;
 92         t++;
 93     }
 94     for(int i=0;i<S;++i)
 95     {
 96         ll x=rand()%(n-1)+1;
 97         x=quick_mod(x,u,n);
 98         for(int i=1;i<=t;++i)
 99         {
100             ll y=quick_mul_mod(x,x,n);
101             if(y==1&&x!=1&&x!=n-1)
102               return false;
103             x=y;
104         }
105         if(x!=1) return false;
106     }
107     return true;
108 }
109 void findpri(ll n)
110 {
111     if(n==1) return;
112     if(Miller_rabin(n))
113     {
114         maxz=max(maxz,n);
115         return;
116     }
117     ll p=n;
118     while(p==n)
119       p=Pollard_rho(p,rand()%(n-1)+1);
120     findpri(p);
121     findpri(n/p);
122 }
123 int main()
124 {
125     srand(time(0));
126     cas=read();
127     while(cas--)
128     {
129         maxz=0;
130         ll n=read();
131         findpri(n);
132         if(maxz==n)/*最大的质因数就是本身*/
133           printf("Prime\n");
134         else printf("%lld\n",maxz);
135     }
136     return 0;
137  } 
时间: 2024-10-20 22:16:27

Pollard rho算法+Miller Rabin算法 BZOJ 3668 Rabin-Miller算法的相关文章

51_1037最长循环节 (miller rabin算法 pollard rho算法 原根)

1037 最长的循环节 V2 基准时间限制:1 秒 空间限制:131072 KB 分值: 320 难度:7级算法题 收藏 关注 正整数k的倒数1/k,写为10进制的小数如果为无限循环小数,则存在一个循环节,求<=n的数中,倒数循环节长度最长的那个数. 1/6= 0.1(6) 循环节长度为1 1/7= 0.(142857) 循环节长度为6 1/9= 0.(1)  循环节长度为1 Input 输入n(10 <= n <= 10^18) Output 输出<=n的数中倒数循环节长度最长的

HDU 3864 D_num Miller Rabin 质数判断+Pollard Rho大整数分解

链接:http://acm.hdu.edu.cn/showproblem.php?pid=3864 题意:给出一个数N(1<=N<10^18),如果N只有四个约数,就输出除1外的三个约数. 思路:大数的质因数分解只能用随机算法Miller Rabin和Pollard_rho,在测试多的情况下正确率是由保证的. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <c

Pollard Rho算法浅谈

Pollard Rho介绍 Pollard Rho算法是Pollard[1]在1975年[2]发明的一种将大整数因数分解的算法 其中Pollard来源于发明者Pollard的姓,Rho则来自内部伪随机算法固有的循环 Pollard Rho算法在其他因数分解算法[3]中不算太出众,但其空间复杂度Θ(1)的优势和好打的代码使得OIer更倾向于使用Pollard Rho算法 毕竟试除法太慢了,谁没事打Pollard Rho不打试除法 Pollard Rho原理 生日悖论 如果一年只有365天(不计算闰

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

\(\\\) Miller-Rabin 素性测试 考虑如何检验一个数字是否为素数. 经典的试除法复杂度 \(O(\sqrt N)\) 适用于询问 \(N\le 10^{16}\) 的时候. 如果我们要把询问范围加到 \(10^{18}\) ,再多组询问呢? Miller 和 Rabin 建立了Miller-Rabin 质数测试算法. \(\\\) Fermat 测试 首先我们知道费马小定理: \[ a^{p-1}\equiv 1\pmod p \] 当且仅当 \(p\) 为素数时成立. 逆命题是

GCD &amp; LCM Inverse POJ 2429(Pollard Rho质因数分解)

原题 题目链接 题目分析 这道题用Pollard Rho算法不能交G++,会RE!!!先说一下整体思路,gcd指gcd(a,b),lcm指lcm(a,b).a=x*gcd,b=y*gcd,则x,y互质且有x*y=lcm/gcd,要使a+b最小,也就是x+y最小.这里可以看出我们要做的就是分解lcm/gcd的质因子,然后枚举找出最小的x+y,最后输出a*x,a*y.这里还需要注意一下,题目是要求先输出小的再输出大的.至于Pollard Rho算法这里不讲. 代码 1 #include <cstdi

C++11新特性应用--介绍几个新增的便利算法(不更改容器中元素顺序的算法)

总所周知,C++ STL中有个头文件,名为algorithm,即算法的意思. The header<algorithm>defines a collection of functions especially designed to be used on ranges of elements. 所以,要八一八这个头文件中C++11新增的几个算法,今天主要描述的几个算法不改变容器中元素的顺序. 这里还要啰嗦一句,使用stl算法时,如果与lambda表达式组合使用,那么代码会更加简洁. find_

通用高校排课算法研究----3.基于时间片优先级排课算法

通用高校排课算法研究----3.基于时间片优先级排课算法 3   基于时间片优先级排课算法描述与分析 排课问题实质上是时间.教师.班级.教室.课程这五维关系的冲突问题,要合理的解决这个问题首先要了解排课中的一些基本原则以及排课的一些基本要求. 3.1排课中的基本原则 在课程的编排中应遵循一定的规则, 只有按照基本规则来进行课程的编排才能够减少冲突的发生, 这些基本规则主要有以下几条: 1) 同一班级的学生在同一时间(某些特定的选修课时间除外) 不能安排两门课程 2) 同一教师在同一时间不能安排两

JDK自带的二分查找算法和自己写的普通二分查找算法的比较(java二分查找源代码)

一.描述 解析和比较JDK自带的二分查找算法和自己写的普通二分查找算法,使用二进制位无符号右移来代替除2运算,并使用产生随机数的方法产生一定范围的随机数数组,调用Arrays类的sort()静态方法,对int类型数组进行排序. Math.random()的用法:会产生一个[0,1)之间的随机数(注意能取到0,不能取到1),这个随机数的是double类型,要想返回指定范围的随机数如[m,n]之间的整数的公式:(int)(Math.random()*(m-n+1)+m) 二.源代码 <span st

算法笔记_144:有向图强连通分量的Tarjan算法(Java)

目录 1 问题描述 2 解决方案 1 问题描述 引用自百度百科: 如果两个顶点可以相互通达,则称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.有向图的极大强连通子图,称为强连通分量(strongly connected components). Tarjan算法是基于对图深度优先搜索的算法,每个强连通分量为搜索树中的一棵子树.搜索时,把当前搜索树中未处理的节点加入一个堆栈,回溯时可以判断栈顶到栈中的节点是否为一个强连通分量. 定义D