素数回文 (Miller-Rabin素数测试算法)

素数回文 (Miller-Rabin素数测试算法)_第1张图片

朴素算法能过

#include 
#include 
#include 
#include 
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
#define SIS std::ios::sync_with_stdio(false)
#define space putchar(' ')
#define enter putchar('\n')
#define lson root<<1
#define rson root<<1|1
typedef pair<int,int> PII;
const int mod=998244353;
const int N=2e6+10;
const int M=2e5+10;
const int inf=0x7f7f7f7f;
const int maxx=2e5+7;

ll gcd(ll a,ll b)
{
    return b==0?a:gcd(b,a%b);
}

ll lcm(ll a,ll b)
{
    return a*(b/gcd(a,b));
}

template <class T>
void read(T &x)
{
    char c;
    bool op = 0;
    while(c = getchar(), c < '0' || c > '9')
        if(c == '-')
            op = 1;
    x = c - '0';
    while(c = getchar(), c >= '0' && c <= '9')
        x = x * 10 + c - '0';
    if(op)
        x = -x;
}
template <class T>
void write(T x)
{
    if(x < 0)
        x = -x, putchar('-');
    if(x >= 10)
        write(x / 10);
    putchar('0' + x % 10);
}
ll qsm(int a,int b,int p)
{
    ll res=1%p;
    while(b)
    {
        if(b&1) res=res*a%p;
        a=1ll*a*a%p;
        b>>=1;
    }
    return res;
}

bool judge(ll x)
{
    for(ll i=2;i*i<=x;i++)
    {
        if(x%i==0) return false;
    }
    return true;
}
int main()
{
   // SIS;

   ll x;
   read(x);
   ll ans=x;
   x/=10;
   while(x)
   {
       ans=ans*10+x%10;
       x/=10;
   }
   if(judge(ans))puts("prime");
   else puts("noprime");
   
    return 0;
}

Miller-Rabin素数测试算法模板

#include 
using namespace std;
typedef long long ll ;//miller-rabin素数检验一般应用于大数的快速检测,用long long

//快速乘,代替乘法,防止a乘b爆long long
ll qMul(ll a,ll b,ll mod){
    ll ans = 0;//a乘b等价转化为b个a相加,和快速幂原理一致
    while(b){
        if(b&1) ans = (ans+a)%mod;
        a = (a+a)%mod;
        b>>=1;
    }
    return ans;
}

//快速幂模板
ll qPow(ll base,ll power,ll mod){
    ll ans = 1;
    while(power){
        if(power&1) ans = qMul(ans,base,mod);
        base = qMul(base,base,mod);
        power>>=1;
    }
    return ans%mod;
}

//miller-rabin素数检验函数
bool Miller_Rabin(ll num){
    if(num == 2) return true;  //2为质数
    if(!(num&1)||num<2) return false;//筛掉偶数和小于2的数
    ll s = 0,t = num-1;  //流程中的s和t,2的s次方*t = num-1
    while(!(t&1)){         //当t为偶数的时候,可以继续分解
        s++;
        t>>=1;
    }
    for (int i = 1; i <= 10; i++) {    //进行十次测试即可得到比较准确的判断
        ll a = rand()%(num-1)+1;  //流程中的随机整数a,在1到num-1之间
        ll x = qPow(a,t,num);        //x为二次探测的解
        for(int j = 1;j <= s;j++){      //x平方s次可以得到a的num-1次方
            ll test = qMul(x,x,num); //test为x平方后对num取模
            if(test == 1 && x != 1 && x != num-1) return false;   //如果平方取模结果为1,但是作为解的x不是1或者num-1,说明num不是质数,返回
            x = test;
        }
        if(x != 1) return false;        //费马小定理作最后检测,a的num-1次方对num取模不等于1,一定不是质数
    }
    return true;                          //腥风血雨后仍坚持到最后,基本就是真正的质数了
}

int main(){
    ll num;
    while(cin>>num){
        if(Miller_Rabin(num)) cout<<num<<" is a prime."<<endl;
        else cout<<num<<" is not a prime."<<endl;
    }
    return 0;
}

你可能感兴趣的:(牛客,数学)