高精度快速幂(算法描述)

板子题:

链接

题意

求2^p-1 的后500位和位数;

位数好求,最后一位-1,如果最后一位不是0 ,则无需往前借位,然而2^p不可能出现最后一位是0的情况;所以2^p-1和2^p位数相同。

对于求a^b问题,直接快速幂就好了

然鹅,这道题的数非常大,P(1000<P<31000001000<P<3100000)。最大的一个是P=3021377P=3021377,它有909526位。

普通快速幂

long long quick(int a,int b)
{
    ans=1;
    num=a;
    while(b)
    {
        if(b&1)
            ans*=num;//只需要用数组进行模仿这两个乘法即可
        num*=num;//
        b>>=1;
    }
    return ans;
}

模仿手算

#include<iostream>
#include<cmath>
#include<cstring>
using namespace std;
int n;
int num[505],ans[505],cnt[1005];

void operator_1()
{
    memset(cnt,0,sizeof(cnt));
    for(int i=1;i<=505;i++)
        for(int j=1;j<=505;j++)
        cnt[i+j-1]+=ans[i]*num[j];//运算的规律公式
    for(int i=1;i<505;i++)
        if(cnt[i]>=10)//进位检查并进位
    {
        cnt[i+1]+=cnt[i]/10;
        cnt[i]%=10;
    }
    memcpy(ans,cnt,sizeof(ans));//终于用上了这个复制公式
}

void operator_2()
{
    memset(cnt,0,sizeof(cnt));
    for(int i=1;i<=505;i++)
        for(int j=1;j<=505;j++)
       cnt[i+j-1]+=num[i]*num[j];
    for(int i=1;i<505;i++)
    if(cnt[i]>=10)
    {
        cnt[i+1]+=cnt[i]/10;
        cnt[i]%=10;
    }
    memcpy(num,cnt,sizeof(num));
}

void quick()
{
    while(n)
    {
        if(n&1)
       operator_1();

       operator_2();
        n>>=1;
    }
}

int main ()
{
    ans[1]=1;
    num[1]=2;
    cin>>n;
    cout<<(int)(log10(2)*n+1)<<endl;
    quick();
    ans[1]-=1;
    for(int i=500;i>=1;i--)
    {
        if(i%50==0&&i!=500)
        cout<<endl;
        cout<<ans[i];
    }
    return 0;
}
原文地址:https://www.cnblogs.com/zwx7616/p/11304041.html