Luogu P3383 [template] linear sieve prime number (Miller_Rabin)

Posted by majocmatt on Sat, 02 May 2020 06:41:25 +0200

Title Description

For example, given a range n, you need to deal with the question of whether a certain number M is a prime number (each number is in the range 1-N)

I / O format

Input format:

 

The first row contains two positive integers, N and M, which represent the range and number of queries respectively.

Next, each row of row M contains an integer no less than 1 and no more than N, that is, to ask whether the number is prime.

 

Output format:

 

The output contains line M, and each line is Yes or No, which is the result of each query in turn.

 

Example of input and output

Input example ා 1:copy
100 5
2
3
4
91
97
Output example:copy
Yes
Yes
No
No
Yes

Explain

Space time limit: 500ms 128M

Data size:

For 30% of data: n < = 10000, m < = 10000

For 100% data: n < = 10000000, m < = 100000

Example description:

N=100, indicating that the number of subsequent queries is not greater than 100 and not less than 1.

So 2,3,97 are prime numbers, 4,91 are not prime numbers.

So output Yes, Yes, No, No and Yes in sequence.

 

 

Make up for 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;
}

Topics: C++ less