题目描述
如题,给定一个范围N,你需要处理M个某数字是否为质数的询问(每个数字均在范围1-N内)
输入输出格式
输入格式:
第一行包含两个正整数N、M,分别表示查询的范围和查询的个数。
接下来M行每行包含一个不小于1且不大于N的整数,即询问该数是否为质数。
输出格式:
输出包含M行,每行为Yes或No,即依次为每一个询问的结果。
输入输出样例
说明
时空限制:500ms 128M
数据规模:
对于30%的数据:N<=10000,M<=10000
对于100%的数据:N<=10000000,M<=100000
样例说明:
N=100,说明接下来的询问数均不大于100且不小于1。
所以2、3、97为质数,4、91非质数。
故依次输出Yes、Yes、No、No、Yes。
补一发Miller Rabin
注意开long long
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #define LL long long using namespace std; const LL MAXN=2*1e7+10; const LL INF=1e7+10; inline char nc() { static char buf[MAXN],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,MAXN,stdin),p1==p2)?EOF:*p1++; } inline LL read() { char c=nc();LL x=0,f=1; while(c<‘0‘||c>‘9‘){if(c==‘-‘)f=-1;c=nc();} while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘;c=nc();} return x*f; } LL fastpow(LL a,LL p,LL mod) { LL base=1; while(p) { if(p&1) base=(base*a)%mod; a=(a*a)%mod; p>>=1; } return base; } LL num[]= {2,3,5,7,11,13,17,19}; bool Miller_Rabin(LL n) { if (n==2) return 1; if((n&1)==0||n==1) return false; for (LL i=0; i<8; i++) if (n==num[i]) return 1; LL temp=n-1,t=0,nxt; while((temp&1)==0) temp>>=1,t++; for(LL i=0;i<8;i++) { LL a=num[i]; LL now=fastpow(a,temp,n); nxt=now; for(LL j=1;j<=t;j++) { nxt=(now*now)%n; if(nxt==1&&now!=n-1&&now!=1) return false; now=nxt; } if(now!=1) return false; } return true; } int main() { #ifdef WIN32 freopen("a.in","r",stdin); #else #endif LL N=read(),M=read(); while(M--) { LL opt=read(); if(Miller_Rabin(opt)) printf("Yes\n"); else printf("No\n"); } return 0; }