zoukankan      html  css  js  c++  java
  • 麦森数,高精度快速幂

    洛谷P1045

    首先要求2p-1的结果有多少位,因为减一并不会影响其的位数,所以只要求2p有多少位就可以了,直接看图。

    重点是怎么求2p-1的结果的后500位

    高精度

    首先需要了解一下快速幂的原理,这里就不说了,直接上代码

    long long Mode(long long a,long long b)
        {
            long long sum=1;
            a=a%m;
            while(b>0)
            {
                if(b%2==1)
                sum=(sum*a)%m;//修改
                b/=2;
                a=(a*a)%m;//修改
            }
            return sum;
        }

    高精度的话我们只需要对上述修改的地方做一个大数的处理就可以了

    高精度的思路

    对每个位置上的数单独计算不进位,最后处理的时候统一进位

    void calculute1()
    {
        memset(sav,0,sizeof(sav));//将sav数组全部赋为0
        for(int i=1;i<=500;i++)
            for(int j=1;j<=500;j++)//每一位单独计算
            sav[i+j-1]+=res[i]*f[j];
            for(int i=1;i<=500;i++)//进位处理
            {
                sav[i+1]+=sav[i]/10;//满10进1
                sav[i]%=10;//进位后剩下的部分
            }
            memcpy(res,sav,sizeof(res));//将sav数组复制到res数组中去
    }

    这里取一个33*44作为例子对上述代码的过程进行说明

    快速幂的还有一个部分的原理和上面一个是相同的

    void calculute2()
    {
        memset(sav,0,sizeof(sav));
        for(int i=1;i<=500;i++)
            for(int j=1;j<=500;j++)
            sav[i+j-1]+=f[i]*f[j];
            for(int i=1;i<=500;i++)
            {
                sav[i+1]+=sav[i]/10;
                sav[i]%=10;
            }
            memcpy(f,sav,sizeof(f));
    }

    完整代码

    #include <iostream>
    #include<cmath>
    #include<cstring>
    using namespace std;
    int sav[1001],p,f[1001],res[1001];
    void calculute1()
    {
        memset(sav,0,sizeof(sav));
        for(int i=1;i<=500;i++)
            for(int j=1;j<=500;j++)
            sav[i+j-1]+=res[i]*f[j];
            for(int i=1;i<=500;i++)
            {
                sav[i+1]+=sav[i]/10;
                sav[i]%=10;
            }
            memcpy(res,sav,sizeof(res));
    }
    void calculute2()
    {
        memset(sav,0,sizeof(sav));
        for(int i=1;i<=500;i++)
            for(int j=1;j<=500;j++)
            sav[i+j-1]+=f[i]*f[j];
            for(int i=1;i<=500;i++)
            {
                sav[i+1]+=sav[i]/10;
                sav[i]%=10;
            }
            memcpy(f,sav,sizeof(f));
    }
    int main()
    {
        int p,num;
        cin>>p;
        num=log10(2)*p+1;
        cout<<num<<endl;
        res[1]=1;
        f[1]=2;
        while(p!=0)
        {
            if(p%2==1)
                calculute1();
            p/=2;
            calculute2();
        }
        res[1]--;
        for(int i=500;i>=1;i--)
        {
            if(i!=500&&i%50==0)
                cout<<endl;
                cout<<res[i];
        }
        return 0;
    }
  • 相关阅读:
    C语言常用函数-findfirst()搜索指定磁盘目录里文件函数
    C语言常用函数-getcwd()获取当前工作目录函数
    C语言常用函数目录
    C语言常用函数-_rmdir()建立目录函数
    C语言常用函数-mkdir()建立目录函数
    NX二次开发-UF_DRF_ask_dim_info获得图纸尺寸属于哪个视图和图纸页
    NX二次开发-NXOpenC++属性操作
    VMware虚拟机设置双网卡上网
    FreeCAD二次开发-计算模型是否报错,报错则停止
    NX二次开发-自动将NX标题设置为prt路径
  • 原文地址:https://www.cnblogs.com/zlhdbk/p/10602968.html
Copyright © 2011-2022 走看看