@nlogn
2018-12-01T10:46:26.000000Z
字数 2790
阅读 689
如题,给定一个范围,你需要处理个某数字是否为质数的询问(每个数字均在范围内)
第一行包含两个正整数,分别表示查询的范围和查询的个数。
接下来行每行包含一个的整数,即询问该数是否为质数。
输出包含行,每行为或,即依次为每一个询问的结果。
100 5
2
3
4
91
97
Yes
Yes
No
No
Yes
时空限制:
数据规模:
对于30%的数据:,
对于100%的数据:,
,说明接下来的询问数均不大于且不小于。
所以为质数,非质数。
故依次输出Yes、Yes、No、No、Yes
。
先来看一下素数的定义:
质数定义为在大于的自然数中,除了和它本身以外不再有其他因数。
————By 百度百科
所以就诞生了最简单的筛素数的方法:
我们对于传入的从枚举到,每个数取模一下,从而判断是不是素数。
bool is_prime(int n){
if(n==1) return false;
if(n==2) return true;
for(register int i=2;i<=n-1;i++){
if(n%i==0) return false;
}
return true;
}
这种做法的时间复杂度为,显然,当甚至更大的时候,肯定就会到飞起。
本做法得分:
qwq记录
通过几次尝试之后,我们可以发现,因数总是成对以为轴成轴对称,所以:
我们对于传入的,只需从枚举到即可。
bool is_prime(int n);{
if(n==1) return false;
if(n==2) return true;
for(register int i=2;i<=sqrt(n);i++)
if(n%i==0) return false;
return true;
}
上述程序时间复杂度为,大大减少了程序的复杂度。
本做法得分:
qwq记录
那么,还能够继续优化吗?
刚学的时候,唐只讲到优化,sb的我就以为这是最快的了。
直到,看到了,某太阳:%3462^&sdh234>>>>dkfjlw
的一通哔哩哔哩筛法,嗯。。。。
证明:摘自质数判定方法。
证明:令,将大于等于的自然数表示如下:
可以看到,不在的倍数两侧,即两侧的数为由于,
所以它们一定不是素数,再除去本身,显然,素数要出现只可能出现在的相邻两侧。
所以,基于以上条件,我们假如要判定的数为,则必定是或的形式,对于循环中其中如果能被整除,则至少得是一个偶数,
但是或的形式明显是一个奇数,故不成立;另外,如果能被整除,则至少能被整除,
但是能被整除,故或(即)不可能被整除,故不成立。综上,循环中只需要考虑和的情况
即循环的步长可以定为,每次判断循环变量和的情况即可,代码如下:
bool is_prime(int n)
{
if(n==1) return false;
if(n==2||n==3) return true;
if(n%6!=1&&n%6!=5) return false;
for(register int i=5;i*i<=n;i+=6)
if(n%i==0||n%(i+2)==0) return false;
return true;
}
理论上述程序的时间复杂度约为。
本做法得分:当然是
qwq记录
/* Headers */
#include<cstdio>
#include<cctype>
#include<cmath>
/* define */
#define MAXN 100010
using namespace std;
namespace FastIO{
const int BUFSIZE=(1<<20);
char ibuf[BUFSIZE],*is=ibuf,*it=ibuf;
char obuf[BUFSIZE],*os=obuf,*ot=obuf+BUFSIZE;
inline char getch(){
if(is==it)
it=(is=ibuf)+fread(ibuf,1,BUFSIZE,stdin);
return (is==it)?EOF:*is++;
}
inline int getint(){
int res=0,neg=0,ch=getch();
while(!(isdigit(ch)||ch=='-')&&ch!=EOF)
ch=getch();
if(ch=='-'){
neg=1;ch=getch();
}
while(isdigit(ch)){
res=(res<<3)+(res<<1)+(ch-'0');
ch=getch();
}
return neg?-res:res;
}
inline void write(int x){
if(x<0)x=-x,putchar('-');
if(x>10)write(x/10);
putchar(x%10+'0');
}
inline void space(int x){
if(x==0)putchar(' ');
else putchar('\n');
}
}
using namespace FastIO;
/* definitions */
int N,m,q;
/* functions */
bool is_prime(int n){
if(n==1) return false;
if(n==2||n==3) return true;
if(n%6!=1&&n%6!=5) return false;
for(register int i=5;i*i<=n;i+=6)
if(n%i==0||n%(i+2)==0) return false;
return true;
}
int main(int argc,char *argv[]){
scanf("%d%d",&N,&m);
for(int i=1;i<=m;i++){
scanf("%d",&q);
if(is_prime(q)){
printf("Yes\n");
}
else{
printf("No\n");
}
}
return 0;
}