在做这道题之前,我们首先来尝试签到题

签到题

我们定义一个函数:\(qiandao(x)\) 为小于等于 x 的数中与 x 不互质的数的个数。要求 \(\sum\limits _{i=l}^r qiandao(i)\)

容易发现 \(qiandao(x)\) 只需求 \(\phi(x)\),不互质的个数就是另外一半。

那么问题转化为了如何筛出区间 \(\phi\) 的值。考虑到值域最大只有 \(1e12\)。并且区间长度小于一百万,所以可以尝试筛根号以内素数求解。

我们知道欧拉函数计算公式为 \(\prod_{d \mid p}\frac{d-1}{d}\) 其中 d 是 p 的质因数。

于是我们可以通过筛去根号以内每个质数计算大整数区间的欧拉值,而剩下筛不掉的一定是大于根号的质数,这个直接根据上式乘上就行了。

复杂度与自然对数有关,和调和级数类似。

小清新数学题

求解 \(\sum\limits_{i=l}^r\mu(i)\)

现在我们掌握了区间筛积性函数的方法,但是,这道题的数据范围到了 \(1e18\)。我们不可能晒出十亿以内的质数。

那么怎么办呢?

注意到本题求得是莫比乌斯函数,根据莫比乌斯函数的定义,函数值只与质因子的个数有关,我们不需要求出具体的质数是谁,只需要知道有几个就行。

于是我们仍然可以用一百万以内的质数去筛。

剩下的情况分三种:

  1. \(res=q\times p\)
  2. \(res=q\)
  3. \(res=q^2\)

首先对于第一种情况,莫比乌斯函数值并不会改变。

第二种情况,取反即可。

第三种情况,直接就是 0。

第三种情况好判断,只需判断是否满足 \(\sqrt{i}^2==i\) 。

对于一二种情况,实质实在判断 res 是否是素数,于是引出了我们的另一个问题。如何判断一个数是否是素数?

Miller_Rabin 算法

百度百科:

Miller-Rabin算法是目前主流的基于概率的素数测试算法,在构建密码安全体系中占有重要的地位。通过比较各种素数测试算法和对Miller-Rabin算法进行的仔细研究,证明在计算机中构建密码安全体系时, Miller-Rabin算法是完成素数测试的最佳选择。通过对Miller-Rabin 算 法底层运算的优化,可以取得较以往实现更好的性能。[1] 随着信息技术的发展、网络的普及和电子商务的开展, 信息安全逐步显示出了其重要性。信息的泄密、伪造、篡改 等问题会给信息的合法拥有者带来重大的损失。在计算机中构建密码安全体系可以提供4种最基本的保护信息安全的服 务:保密性、数据完整性、鉴别、抗抵赖性,从而可以很大 程度上保护用户的数据安全。在密码安全体系中,公开密钥 算法在密钥交换、密钥管理、身份认证等问题的处理上极其有效,因此在整个体系中占有重要的地位。目前的公开密钥 算法大部分基于大整数分解、有限域上的离散对数问题和椭 圆曲线上的离散对数问题,这些数学难题的构建大部分都需 要生成一种超大的素数,尤其在经典的RSA算法中,生成的素数的质量对系统的安全性有很大的影响。目前大素数的生 成,尤其是随机大素数的生成主要是使用素数测试算法,本 文主要针对目前主流的Miller-Rabin 算法进行全面系统的分析 和研究,并对其实现进行了优化

这个看个热闹就完了,其实这个东西我们只用来判断一个数是否是素数。以下内容说到的 p 默认为质数。

Miller Rabin基于费马小定理:

\[a^{p-1}\equiv 1\pmod{p}
\]

证明:

  1. 对于数 \(a,2a,3a,.....(p-1)a\) 没有 \(p\) 的倍数。

  2. 对于这一列数在模 \(p\) 意义下两两不同余。

  3. 这串数在模 \(p\) 意义下的余数构成 \(p-1\) 的一个排列。

    于是有:

\[a\times 2a\times 3a\times (p-1)a\equiv (p-1)!\pmod{p}
\]

化简左边:

\[a^{p-1}\times (p-1)!\equiv (p-1)!\pmod{p}
\]

由威尔逊定理:

\[(p-1)!\equiv1\pmod{p}
\]

消去 \((p-1)!\) 得证。

费马小定理成立,那么如果费马小定理的逆命题成立我们不就可以判断质数了吗?

可惜,很长时间里人们确实是这样认为的,直到强伪素数被人们发现,例如341。

再来介绍 二次探测定理:

如果满足\(x^2\equiv1\pmod{p}\) 那么 x 的取值只有 1 或者 p-1。

证明:

转换上式:

\[p\mid x^2-1
\]
\[p\mid (x-1)(x+1)
\]

由唯一分解定理得到\(p \mid x+1\) 或 \(p\mid x-1\)

所以 \(x\equiv1 or -1\pmod{p}\)。

如果 x 不满足上式则 p 一定是合数。

所谓 Miller Rabin 就是上面的结合。说白了就是多取几个数多试几次,这样出错的概率极低。

签到题code

#include<bits/stdc++.h>
#define int long long
#define mod 666623333
using namespace std;
int su[10000001],cnt,ans[1000011],len,lst=0,l,r,shu[1000011];
bool bo[10000001];
inline void pre()
{ for(int i=2;i<=1000000;++i)
{ if(!bo[i])su[++cnt]=i;
for(int j=1;j<=cnt and i*su[j]<=1000000;++j)
{ bo[su[j]*i]=1;
if(i%su[j]==0)break;
}
}
}
signed main()
{ pre();scanf("%lld%lld",&l,&r);len=r-l+1;
for(int i=1;i<=len;++i)ans[i]=shu[i]=i+l-1;
for(int i=1;i<=cnt;++i)
{ int base=l/su[i];
for(int j=base;;++j)
{ if(j*su[i]>=l and j*su[i]<=r)
{ ans[j*su[i]-l+1]=(ans[j*su[i]-l+1]/su[i]*(su[i]-1));
while(shu[j*su[i]-l+1]%su[i]==0)shu[j*su[i]-l+1]/=su[i];
}
else if(j*su[i]>r)break;
}
}
for(int i=1;i<=len;++i)
{ if(shu[i]!=1)ans[i]=ans[i]/shu[i]*(shu[i]-1);
lst=(lst+(l+i-1-ans[i]))%mod;
}
printf("%lld\n",lst);
}

小清新数学题code

#include<bits/stdc++.h>
#define int long long
#define N 1000500
#define mfb __int128
using namespace std;
int su[N],cnt,tot,u[N],shu[N];
bool bo[N];long long l,r,ans;
inline int qpow(mfb a,mfb b){int mod=b+1,base=1;a%=mod;while(b){if(b&1)base=base*a%mod;a=a*a%mod;b>>=1;}return base;}
inline bool miller(int x)
{return (qpow(2,x-1)==1 );}
signed main()
{ scanf("%lld%lld",&l,&r);u[1]=1;
int lim=1e6;
for(int i=2;i<=lim;++i)
{ if(!bo[i])su[++cnt]=i,u[i]=-1;
for(int j=1;j<=cnt and i*su[j]<=lim;++j)
{ bo[i*su[j]]=1;u[i*su[j]]=-u[i];
if(i%su[j]==0){u[i*su[j]]=0;break;}
}
}
for(int i=l;i<=r;++i)u[i-l+1]=1,shu[i-l+1]=i;
for(int i=1;i<=cnt;++i)
{ int be=l/su[i]+(l%su[i]!=0);
for(int j=be;j*su[i]<=r;++j)
{ int id=j*su[i]-l+1;
int cnt=0;
while(shu[id]%su[i]==0)shu[id]/=su[i],++cnt,u[id]*=-1;
if(cnt>=2)u[id]=0;
}
}
for(int i=l;i<=r;++i)if(shu[i-l+1]!=1)
{ if((long long )sqrt(shu[i-l+1])*sqrt(shu[i-l+1])==shu[i-l+1]){u[i-l+1]=0;continue;}
if(miller(shu[i-l+1]))u[i-l+1]*=-1;
}
for(int i=l;i<=r;++i)ans+=u[i-l+1];printf("%lld\n",ans);
}

由于数据比较水,我又比较懒,上面只用了 femart。

Miller Rabin

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=100000+5;
int a[3]={2,7,61};
ll qm(ll x,ll y,ll mod){
ll ret=1;
while(y){
if(y&1) (ret*=x)%=mod;
(x*=x)%=mod;
y>>=1;
}
return ret;
}
bool che(ll a,ll x){
int s=0;
ll t;
ll lp=x-1;
while(!(lp&1)){
s++;
lp>>=1;
}
t=qm(a,lp,x);
if(t==1||t==x-1) return true;
if(s==0) return false;
ll las=t;
for(int i=0;i<s;i++){
las=t;
(t*=t)%=x;
if(t==1&&(las!=1&&las!=x-1)) return 0;
}
if(t!=1) return 0;
return 1;
}
int n,m;
bool M_R(ll n){
if(n==2||n==7||n==61) return true;
if(n<2||n%2==0||n%7==0||n%61==0) return false;
for(int i=0;i<3;i++){
ll b=a[i];
if(b!=n){
if(!che(b,n)) return false;
}
}
return true;
}
int main(){
scanf("%d%d",&n,&m);
ll x;
for(int i=1;i<=m;i++){
scanf("%lld",&x);
if(x==2||x==3||x==5||x==7||x==11||x==13){
puts("Yes");continue;
}
if(x%2==0||x%3==0||x%5==0||x%7==0||x%11==0||x%13==0){
puts("No");continue;
}
if(M_R(x)) puts("Yes");
else puts("No");
}
return 0;
}

Miller Rabin的板子为转载,上面过的是线性筛。

Miller Rabin 详解 && 小清新数学题题解的更多相关文章

  1. Mysql5.5升级到5.6步骤详解 小版本大版本

    http://blog.csdn.net/i_team/article/details/9935693 小版本升级,先关闭数据库,然后mv直接全部替换掉mysql目录下的bin/ ,lib/ ,sha ...

  2. 微信小程序开发详解——小程序,大颠覆!

    微信小程序开发 联系 苏念 188.1414.7927  微信小程序系统开发 微信新功能开发 小程序开发 小程序怎么开发 app小程序开发 简化小程序开发 微信小程序定制 小程序制作 开发微信小程序  ...

  3. 最小割树(Gomory-Hu Tree)求无向图最小割详解 附 BZOJ2229,BZOJ4519题解

    最小割树(Gomory-Hu Tree) 前置知识 Gomory-Hu Tree是用来解决无向图最小割的问题的,所以我们需要了解无向图最小割的定义 和有向图类似,无向图上两点(x,y)的割定义为一个边 ...

  4. 命令提示符(cmd)中的tracert命令详解(小技巧)

    tracert也被称为Windows路由跟踪实用程序,在命令提示符(cmd)中使用tracert命令可以用于确定IP数据包访问目标时所选择的路径.本文主要探讨了tracert命令的各个功能. 百度经验 ...

  5. jQuery.validator 详解二

    前言:上一篇详细的介绍了jQuery.validator( 版本v1.13.0 )的验证规则,这一篇重点讲述它的源码结构,及如何来对元素进行验证,错误消息提示的内部实现 一.插件结构(组织方式) 在讲 ...

  6. jQuery.validator 详解

    jQuery.validator 详解二 前言:上一篇详细的介绍了jQuery.validator( 版本v1.13.0 )的验证规则,这一篇重点讲述它的源码结构,及如何来对元素进行验证,错误消息提示 ...

  7. expect学习笔记及实例详解【转】

    1. expect是基于tcl演变而来的,所以很多语法和tcl类似,基本的语法如下所示:1.1 首行加上/usr/bin/expect1.2 spawn: 后面加上需要执行的shell命令,比如说sp ...

  8. vuex的使用及持久化state的方式详解

    vuex的使用及持久化state的方式详解 转载  更新时间:2018年01月23日 09:09:37   作者:baby格鲁特    我要评论 这篇文章主要介绍了vuex的使用及持久化state的方 ...

  9. Miller Rabin算法详解

    何为Miller Rabin算法 首先看一下度娘的解释(如果你懒得读直接跳过就可以反正也没啥乱用:joy:) Miller-Rabin算法是目前主流的基于概率的素数测试算法,在构建密码安全体系中占有重 ...

随机推荐

  1. Ubuntu 16.04LTS下eclipse连接mysql

    第一部分:打开eclipse,新建一个web工程,新建一个类db_test.java(jdbc连接mysql的原理自行百度) import java.sql.*; public class db_te ...

  2. 安装配置Linux Squid代理服务器

    1.代理服务器的工作机制 代理服务器的工作机制像生活中的代理商,假设自己的机器为A,想获得的数据由服务器B提供,代理服务器为C,那么连接过程是,A需要B的数据,并直接和C连接:C接受到A的数据请求之后 ...

  3. i++ ++i 理解

    i++与++i怎么运算,解决办法: i++规则是在表达式中先取i的值使用,后让i的值变化成加1后的值. 举例:如在式中 j=i++,他就会变成这样的两步,第一步先执行j=i,第二步执行i=i+1. + ...

  4. vue之 分页封装

    npm 下载 npm i element-ui -S components 创建 Page 文件夹 创建 Page.vue 文件 vue 文件 <template>   <div c ...

  5. Appium自动化(6) - 控件定位工具之uiautomatorviewer 的详细介绍

    如果你还想从头学起Appium,可以看看这个系列的文章哦! https://www.cnblogs.com/poloyy/category/1693896.html 前言 app定位不如web定位那么 ...

  6. Docker(34)- 如何修改 docker 容器的目录映射

    如果你还想从头学起 Docker,可以看看这个系列的文章哦! https://www.cnblogs.com/poloyy/category/1870863.html 问题背景 docker run ...

  7. vue.js框架图片上传组件

    html: <div id="app"> <div class="hello"> <div class="upload& ...

  8. linux系列之:告诉他,他根本不懂kill

    目录 简介 使用kill来杀死进程 kill的深入用法 僵尸进程和kill java thread dump 总结 简介 和很多程序员打过交道,这些程序员可能熟知for遍历的好几种写法,但是却对写出来 ...

  9. hyperf从零开始构建微服务(二)——构建服务消费者

    阅读目录 构建服务消费者 安装json rpc依赖 安装JSON RPC客户端 server配置 编写业务代码 编写服务消费者类 consumer配置 配置 UserServiceInterface ...

  10. 聊聊ReentrantLock基于AQS的公平锁和非公平锁的实现区别

    ReentrantLock锁的实现是基于AQS实现的,所以先简单说下AQS: AQS是AbstractQueuedSynchronizer缩写,顾名思义:抽象的队列同步器,它是JUC里面许多同步工具类 ...