欧拉筛法模板and 洛谷 P3383 【模板】线性筛素数(包括清北的一些方法)
题目描述
如题,给定一个范围N,你需要处理M个某数字是否为质数的询问(每个数字均在范围1-N内)
输入格式
第一行包含两个正整数N、M,分别表示查询的范围和查询的个数。
接下来M行每行包含一个不小于1且不大于N的整数,即询问该数是否为质数。
输出格式
输出包含M行,每行为Yes或No,即依次为每一个询问的结果。
当然这是一道很裸的板子题,但是却牵扯到了一个非常有用的东西:
素数筛法
首先,我们知道素数筛法主要就是以下几种
第一:
无脑筛
其实就是从2到n遍历一遍,没什么可讲的,顶多把n优化成sqrt(N),所是这种算法的时间复杂度就是O(sqrt(N))不可否定的是,这是已知判断单一数的最快而且是最精准的方法了,绝对不会出错
第二:
Miller-rabin素性测试
如果n为素数,取a<n,设n-1=d*2r,则要么ad≡1(mod n)要么存在0<=i<r,使得ad*2^t≡-1(mod n),要么存在0<=i<r,使得ad*2^t≡-1(mod n)(有可能都满足)
对于任意一个a,如果满足这两个条件,n有可能是质数,但a如果不满足这两个条件中的任何一个,它一定不是质数。找k个a,如果都满足这两个条件,k-1个“更”有可能是质数
在选取k的时候,最好选取2,3,5,7,13,29,37,89至少保证int范围内不会出错
因为筛法的不确定性来自于随机的a,但是当选取的数足够好,就没有问题;
如果n是素数,取a<n,舍n-1=d*2r,则要么ad≡1(mod n),要么存在0<=i<r,使得a
部分代码:
int gg[]={,,,,,,,};
long long kuaisumi(long long a,long long b1,long long c)
{
long long i=a;
while(b1)
{
if(b1&)
{
s=(s*i)%c;
}
i=(i*i)%c;
b1>>=;
}
return s%c;
}
bool miller_rabin(int a,int n)
{
int d=n-,r=;
while(d%==)
d/=,r++;
int x=kuaisumi(a,d,n);
if(x==)return true;
for(int i=;i<r;i++)
{
if(x==n-)return true ;
x=(long long )x*x%n;
}
return false;//可以对照素性测试看
}
bool is_prime (int n)
{
if(n<=)return false ;
for(int a=;a<;a++)
if(n==gg[a])return true;//一个个试
for(int a=;a<;a++)
if(!miller_rabin(gg[a],n))return false;
return true;
}
现在我们讲一下筛某一个范围的数的方法,
第三:
埃拉托色尼筛法(埃氏筛)
主要思想就是把所有质数的整倍数筛掉,速度比较快,也不难想,时间复杂度o(nloglogn)
代码实现:
#include<stdio.h>
#include<math.h>
int main()
{ int i,j,k;
int a[];
for(i=;i<=;i++) a[i]=i;
a[]=; //先挖掉a[1] for(i=;i<sqrt();i++){
for(j=i+;j<=;j++){
if(a[i]!=&&a[j]!=){
if(a[j]%a[i]==){
a[j]=; //把非素数挖掉,不是素数的都赋值为0
}
}
}
}
printf("\n");
for(i=,k=;i<=;i++){
if(a[i]!=){ //选出值不为0的数 即素数
//cout<<" "<<a[i];
printf("%d ",a[i]);
k++;
} if(k==){
printf("\n");
k=;
}
}
printf("\n"); return ;
}
还有一个是对埃氏筛的优化,叫做欧拉筛,也叫作线性筛
代码实现:
#include<cstdio>
#include<iostream>
using namespace std;
int tot,n,b[],pri[];//b[i]存的是i是否为质数,0为质数,1为合数;pri[i]存的是第i个质数
inline void shai()
{
//b[1]=1;
for(int i=;i<=n;i++)//从2到n,因为1不是质数可以跳过,当然有的时候可能会用到b[1],这个时候需要赋特值如上
{
if(!b[i])pri[++tot]=i;
for(int j=;j<=tot&&i*pri[j]<=n;++j)
{
b[i*pri[j]]=;
if(i%pri[j]==)break;//如果i%pri[j]==0,就说明是i的倍数的数一定是某质数的倍数,这个时候就可以把它去掉从而节省时间
}
}
}
int main()
{
cin>>n;
shai();
for(int i=;i<=tot;i++)
{
cout<<pri[i]<<endl;//这里是输出n以内的质数,如果想判断一个数是否为质数可以看b[i]
}
}
所有的筛法就讲完了,最后我们贴一下AC代码:
#include<cstdio>
#include<iostream>
#include<cmath>
using namespace std;
int tot,n,m,b[],pri[],a[];
inline void shai()
{
for(int i=;i<=n;i++)
{
if(!b[i])pri[++tot]=i;
for(int j=;j<=tot&&i*pri[j]<=n;++j)
{
b[i*pri[j]]=;
if(i%pri[j]==)break;
}
}
}
int main()
{
cin>>n>>m;
shai();
for(int i=;i<=m;i++)
{
cin>>a[i];
}
for(int i=;i<=m;i++)
{
if(a[i]==)
{
cout<<"No"<<endl;
}
else
{
if(b[a[i]]==)
cout<<"Yes"<<endl;
else
cout<<"No"<<endl;
}
}
return ;
}
欧拉筛法模板and 洛谷 P3383 【模板】线性筛素数(包括清北的一些方法)的更多相关文章
- [洛谷P3383][模板]线性筛素数-欧拉筛法
Description 如题,给定一个范围N,你需要处理M个某数字是否为质数的询问(每个数字均在范围1-N内) Input&Output Input 第一行包含两个正整数N.M,分别表示查询的 ...
- 【埃氏筛】洛谷P3383埃氏筛模板
思路: 如果我们要筛出 [1, n] 内的所有素数,使用 [1, √n] 内的素数去筛就可以了 设bool型数组 a,a[i] 表示 i 是否被某个素数筛过 从 2 开始枚举每个数 i: 若 a[i] ...
- 洛谷 P3383 【模板】线性筛素数-线性筛素数(欧拉筛素数)O(n)基础题贴个板子备忘
P3383 [模板]线性筛素数 题目描述 如题,给定一个范围N,你需要处理M个某数字是否为质数的询问(每个数字均在范围1-N内) 输入输出格式 输入格式: 第一行包含两个正整数N.M,分别表示查询的范 ...
- 欧拉筛法模板&&P3383 【模板】线性筛素数
我们先来看欧拉筛法 •为什么叫欧拉筛呢?这可能是跟欧拉有关 •但是为什么叫线性筛呢?因为它的复杂度是线性的,也就是O(n),我们直接来看代码 #include<cstdio> #inc ...
- 【模板】埃拉托色尼筛法 && 欧拉筛法 && 积性函数
埃拉托色尼筛法 朴素算法 1 vis[1]=1; 2 for (int i=2;i<=n;i++) 3 if (!vis[i]) 4 { 5 pri[++tot]=i; 6 for (int j ...
- 素数筛总结篇___Eratosthenes筛法和欧拉筛法(*【模板】使用 )
求素数 题目描述 求小于n的所有素数的数量. 输入 多组输入,输入整数n(n<1000000),以0结束. 输出 输出n以内所有素数的个数. 示例输入 10 0 示例输出 4 提示 以这道题目为 ...
- 洛谷P3383 【模板】线性筛素数
P3383 [模板]线性筛素数 256通过 579提交 题目提供者HansBug 标签 难度普及- 提交 讨论 题解 最新讨论 Too many or Too few lines 样例解释有问题 ...
- 洛谷 P3383 【模板】线性筛素数
P3383 [模板]线性筛素数 题目描述 如题,给定一个范围N,你需要处理M个某数字是否为质数的询问(每个数字均在范围1-N内) 输入输出格式 输入格式: 第一行包含两个正整数N.M,分别表示查询的范 ...
- 『素数 Prime判定和线性欧拉筛法 The sieve of Euler』
素数(Prime)及判定 定义 素数又称质数,一个大于1的自然数,除了1和它自身外,不能整除其他自然数的数叫做质数,否则称为合数. 1既不是素数也不是合数. 判定 如何判定一个数是否是素数呢?显然,我 ...
随机推荐
- mybatis中:selectKey返回最近插入记录的id
<insert id="insert" parameterType="com.lls.model.Employee"> <!-- select ...
- WPF开发为按钮提供添加,删除和重新排列ListBox内容的功能
介绍 我有一种情况,我希望能够将项目添加到列表中,并在列表中移动项目,这似乎是使用a的最简单方法ListBox.我立刻想到了如何以通用的方式做到这一点,然后,也许,可以使用行为来做到这一点.这似乎是一 ...
- nginx配置静态项目
当nignx可以加载下面的这个service时 server { listen 8085; server_name 1.192.60.82; location / { root /etc/nginx ...
- Angualr学习笔记
0.安装即环境初始化 下载node至windows,点击安装,所有环境变量直接OK: linux下载tar后,解压,在/etc/profile的path路径下增加node执行路径: export PA ...
- Proxmox VE登陆的时候提示没有有效的订阅You do not have a valid subscription for this server. Please visit www.proxmox.com to get a list of available options.
问题描述: 用的是免费版的,所以每次都提示这个没有有效的订阅挺烦的 解决方法: 修改文件/usr/share/javascript/proxmox-widget-toolkit/proxmoxlib. ...
- centos7防火墙开放端口等命令
CentOS 7 开放防火墙端口 命令 最近公司新的server要求用CentOS7, 发现以前CentOS 6 系列中的 iptables 相关命令不能用了,查了下,发现Centos 7使用fire ...
- VMware虚拟机上网络连接解决方案
VMware虚拟机上网络连接解决方案 作者:凯鲁嘎吉 - 博客园http://www.cnblogs.com/kailugaji/ 从虚拟机上连接外部网络,需要设置以下几个地方. 1.服务 (1)打开 ...
- python之函数对象、函数嵌套、名称空间与作用域、装饰器
一 函数对象 一 函数是第一类对象,即函数可以当作数据传递 #1 可以被引用 #2 可以当作参数传递 #3 返回值可以是函数 #3 可以当作容器类型的元素 二 利用该特性,优雅的取代多分支的if de ...
- exgcd
int exgcd(int a,int b,int &x,int &y){ if (b==0){ x=1,y=0; return a; } int d=exgcd(b,a%b,y,x) ...
- HTML多图无缝循环翻页效果
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...