zoukankan      html  css  js  c++  java
  • 梅森素数应用 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;
    }
    
  • 相关阅读:
    python yield 理解
    创建loop设备
    git 添加submodule 以及更名
    用了linux 这么久,终于发现一个需要硬连接的地方
    gdb 查看内存
    att 汇编 helloworld
    ln 创建连接和mount -bind用法
    区间DP
    数位DP
    VS反汇编分析
  • 原文地址:https://www.cnblogs.com/pprp/p/7663436.html
Copyright © 2011-2022 走看看