Miller-Rabin学习笔记
首先给出两个定理:
1.费马小定理
设p是一个素数,a是一个整数,且不是p的倍数,那么
\(a^{p−1} \equiv\ 1 \pmod p\)
2.二次探测定理
若\(p\)是素数,\(x\)是一个正整数,且\(x^2\ mod\ p\ =\ 1\),那么\(x \equiv \pm 1 \pmod p\)
QwQ经过验证,发现费马小定理的逆定理是不成立的,但是,我们可以运用费马小定理的逆否命题来筛掉一些素数,然后接着用二次探测定理来筛
设被测的数为n,取一个比n小的正整数a,设\(n-1=d\times 2^r\),若n是素数,则要么\(a^d\ mod\ n\ =\ 1\),要么存在一个i,满足\(0 \le i\ <\ r\)且$a^{d\times 2^i}\ \ mod\ \ n\ =\ -1\ $
算法实现的过程大致是:
对于要判断的数n
1.先判断是不是2,是的话就返回true。
2.判断是不是小于2的,或合数,是的话就返回false。
3.令n-1=u*2^t,求出u,t,其中u是奇数。
4.听亢神的话,将a选为2,7,61,24251就可以了!
根据费马小定理,如果a^(n-1)≡1(mod p)那么n就极有可能是素数,如果等式不成立,那肯定不是素数了
因为n-1=u*2t,所以a(n-1)=a(u*2t)=(au)(2^t)。
5.所以我们令x=(a^u)%n
6.然后是t次循环,每次循环都让y=(x*x)%n,x=y,这样t次循环之后x=a(u*2t)=a^(n-1)了
7.因为循环的时候y=(x*x)%n,且x肯定是小于n的,正好可以用二次探测定理,
如果(x^2)%n1,也就是y等于1的时候,假如n是素数,那么x1||x==n-1,如果x!=1&&x!=n-1,那么n肯定不是素数了,返回false。
8.运行到这里的时候x=a^(n-1),根据费马小定理,x!=1的话,肯定不是素数了,返回false
对每一个上述的底数,都做一遍 就可以了
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define ll long long
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while (!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
while (isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}
ll a,k[10];
ll qsc(ll i,ll j,ll mod)
{
ll ans=0;
while (j)
{
if (j&1) ans=(ans+i)%mod;
i=(i+i)%mod;
j>>=1;
}
return ans;
}
ll qsm(ll i,ll j,ll mod)
{
ll ans=1;
while (j)
{
if (j&1) ans=(ans*i)%mod;
i=(i*i)%mod;
j>>=1;
}
return ans;
}
int t;
int n,m;
bool miller_rabin(ll x)
{
if (x==2 || x==7 || x==61 || x==24251) return true;
if (x==1) return false;
ll t = x-1,mi=0; //将x-1分解成t*2^mi
while (!(t&1))
{
t>>=1;
mi++;
}
for (int i=1;i<=4;i++)
{
ll a=k[i];
ll ymh = qsm(a,t,x); //a^t
for (int j=1;j<=mi;j++)
{
ll front = ymh;//ymh
ymh=qsc(ymh,ymh,x);//ymh^2 这里运用了二次探测定理
if (ymh==1 && front!=1 && front!=x-1) return false;
}
if (ymh!=1) return false; //费马小定理的逆否命题
}
return true;
}
int main()
{
scanf("%d%d",&n,&m);
k[1]=2;
k[2]=7;
k[3]=61;
k[4]=24251;
while (m--)
{
ll x;
scanf("%lld",&x);
if (miller_rabin(x)) printf("Yes\n");
else printf("No\n");
}
return 0;
}
Miller-Rabin学习笔记的更多相关文章
- Miller Rabin算法学习笔记
定义: Miller Rabin算法是一个随机化素数测试算法,作用是判断一个数是否是素数,且只要你脸不黑以及常数不要巨大一般来讲都比\(O(\sqrt n)\)的朴素做法更快. 定理: Miller ...
- Miller_Rabbin&&Pollard_Rho 学习笔记
占坑,待填 I Intro 首先我们考虑这样一个问题 给定一个正整数\(p(p<=1e8)\),请判断它是不是质数 妈妈我会试除法! 于是,我们枚举$ \sqrt p$ 以内的所有数,就可以非常 ...
- EF6 学习笔记(五):数据库迁移及部署
EF6学习笔记总目录:ASP.NET MVC5 及 EF6 学习笔记 - (目录整理) 原文地址:Code First Migrations and Deployment 原文主要讲两部分:开发环境下 ...
- MySql学习笔记(一)之DQL常用查询
MySql学习笔记(一)之DQL常用查询 前言:mysql是中小型的数据库软件,SQL语言分为DDL,DCL,DML,DQL四种,在这里重点讲解DQL的单表查询. 正文:在学习mysql单表查询之前, ...
- js学习笔记:webpack基础入门(一)
之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...
- PHP-自定义模板-学习笔记
1. 开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2. 整体架构图 ...
- PHP-会员登录与注册例子解析-学习笔记
1.开始 最近开始学习李炎恢老师的<PHP第二季度视频>中的“章节5:使用OOP注册会员”,做一个学习笔记,通过绘制基本页面流程和UML类图,来对加深理解. 2.基本页面流程 3.通过UM ...
- 2014年暑假c#学习笔记目录
2014年暑假c#学习笔记 一.C#编程基础 1. c#编程基础之枚举 2. c#编程基础之函数可变参数 3. c#编程基础之字符串基础 4. c#编程基础之字符串函数 5.c#编程基础之ref.ou ...
- JAVA GUI编程学习笔记目录
2014年暑假JAVA GUI编程学习笔记目录 1.JAVA之GUI编程概述 2.JAVA之GUI编程布局 3.JAVA之GUI编程Frame窗口 4.JAVA之GUI编程事件监听机制 5.JAVA之 ...
- seaJs学习笔记2 – seaJs组建库的使用
原文地址:seaJs学习笔记2 – seaJs组建库的使用 我觉得学习新东西并不是会使用它就够了的,会使用仅仅代表你看懂了,理解了,二不代表你深入了,彻悟了它的精髓. 所以不断的学习将是源源不断. 最 ...
随机推荐
- Linux系统的ssh与sshd服务
当主机中开启openssh服务,那么就对外开放了远程连接的接口 ssh为openssh服务的客户端,sshd为openssh服务的服务端 远程管理工具ssh具有数据加密传输.网络开销小以及应用平台范围 ...
- Reinforcement Learning 强化学习入门
https://www.zhihu.com/question/277325426 https://github.com/jinglescode/reinforcement-learning-tic-t ...
- Linux常用命令 - nl命令详解
21篇测试必备的Linux常用命令,每天敲一篇,每次敲三遍,每月一循环,全都可记住!! https://www.cnblogs.com/poloyy/category/1672457.html 显示行 ...
- dotnet 读 WPF 源代码笔记 渲染收集是如何触发
在 WPF 里面,渲染可以从架构上划分为两层.上层是 WPF 框架的 OnRender 之类的函数,作用是收集应用程序渲染的命令.上层将收集到的应用程序绘制渲染的命令传给下层,下层是 WPF 的 GF ...
- 一文读懂Redis
目录结构如下: 简介 Redis是一个高性能的key-value数据库.Redis对数据的操作都是原子性的. 优缺点 优点: 基于内存操作,内存读写速度快. Redis是单线程的,避免线程切换开销及多 ...
- 远程线程注入DLL突破session 0 隔离
远程线程注入DLL突破session 0 隔离 0x00 前言 补充上篇的远程线程注入,突破系统SESSION 0 隔离,向系统服务进程中注入DLL. 0x01 介绍 通过CreateRemoteTh ...
- 自定义组件 v-model 的使用
关于自定义组件如何使用 v-model,本章直讲如何使用: 一. $emit('input', params) // 父组件中 <template> <article> {{f ...
- freeswitch 编译安装后的配置
--------------------FreeSWITCH configuration------------Locations: prefix: /usr/local/freeswitchexec ...
- 运行FreeSWITCH的命令行参数
一般来说,FreeSWITCH 不需要任何命令行参数就可以启动,但在某些情况下,你需要以一些特殊的参数启动.在此,仅作简单介绍.如果你知道是什么意思,那么你就可以使用,如果不知道,多半你用不到. 使用 ...
- pytest+allure基础知识
介绍 pytest是基于unittest开发的另一款更高级更好用的单元测试框架 支持参数化 执行测试过程中可以将某些测试跳过(skip),或者对某些预期失败的case标记成失败 支持运行由 nose, ...