• 梅森素数应用 nefu 120


    梅森素数

    定义:

    • if m是一个正整数 and 2^m-1是一个素数 then m是素数
    • if m是一个正整数 and m是一个素数 then M(m)=2^m-1被称为第m个梅森数
    • if p是一个素数 and M(p)是一个素数 then M(p)被称为梅森素数

    Lucas-Lehmer判定法:判定一个梅森数是否是梅森素数

    设p是素数,第p个梅森数为M(p)为2^p-1,r1 = 4,对于k >= 2

    r(k) = r(k+1)^2-2(modM(p)), 0 ⇐ r(k) ⇐ M(p)

    可以得到r(k)序列,则有M(p)是素数,当且仅当r(p-1) = 0(mod M(p))

    推论:设p是素数,M(p)为第p个梅森数,则算法复杂度为O(n^3)

    梅森素数 - nefu 120

    思路:R.1 = 4;R.k = (R.k-1 ^ 2 - 2) % Mp;

    如果R.p-1 == 0,则是梅森素数,否则不是。 特殊判断:p == 2,即Mp = 3是梅森素数。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    
    using namespace std;
    typedef long long ll;
    
    ll multi(ll a, ll b, ll m)
    {
        ll ret = 0;
        while(b>0)
        {
            if(b&1)
            {
                ret = (ret+a)%m;
            }
            b >>= 1;
            a = (a<<1)%m;
        }
        return ret;
    }
    int main()
    {
        ll sum = 1, data[66], tmp;
        int n, p;
        data[1] = 4;
        cin >> n;
        while(n--)
        {
            sum = 1;
            cin >> p;
            sum <<= p;
            sum -= 1;
            for(int i = 2; i <= p-1; i++)
            {
                tmp = multi(data[i-1],data[i-1],sum);
                data[i] = (tmp-2)%sum;
            }
            if(p == 2)
                cout << "yes" << endl;
            else
            {
                if(data[p-1] == 0)
                    cout << "yes" <<endl;
                else
                    cout << "no" << endl;
            }
        }
        return 0;
    }
    
    

    模板:

    long long multi(long long a, long long b, long long m){//实现a * b % m的操作,用2 * 3 = 6模拟一下就懂了
        long long ans = 0;
        while(b > 0){
            if(b & 1)  ans = (ans+a) % m;
            b >>= 1;
            a = (a<<1) % m;
        }
        return ans;
    }
    //判断是否是梅森素数
    bool is_msPrime(int p){
        long long r[70];
        long long m = 1;
        m <<= p;  m -=1;//求出Mp;
        r[1] = 4LL;
        if(p == 2)  return true;
        for(int i = 2; i <= p-1; ++i)
            r[i] = (multi(r[i-1],r[i-1],m)-2) % m;
        if(r[p-1] == 0)  return true;
        return false;
    }
    
  • 相关阅读:
    ECMAScript5之Object学习笔记(二)
    ECMAScript5之Object学习笔记(一)
    【笔记】css 自定义select 元素的箭头样式
    【笔记】h5 页面唤起电话呼叫
    【笔记】vue-cli 打包后路径问题出错的解决方法
    【笔记】BFC 模型知识整理
    【笔记】浏览器的缓存
    【笔记】web 的回流与重绘及优化
    【js 笔记】读阮一峰老师 es6 入门笔记 —— 第二章
    【js 笔记】读阮一峰老师 es6 入门笔记 —— 第一章
  • 原文地址:https://www.cnblogs.com/pprp/p/7663436.html
Copyright © 2020-2023  润新知