【高精度+快速幂】 麦森数

【题目大意】从文件中输入P(1000<P<3100000),计算2^{p}-1的位数和最后500位数字(用十进制高精度数表示)

【思路】高精度+快速幂,代码实现有点烦,但至少比高精减要好。。。

对于位数,首先可以确定2^{p}-12^{p}的位数一定是相同的。因为2的若干次方最后一位一定是大于0的。

考虑把2^{p}的底数转化为10。因为10^{n}位数就是n+1。由于10^{log_{10}2}=2那么可以把2替换成10^{log_{10}2}2^{p}就变成了10^{log_{10}2}^{p},那么位数就是{log_{10}2}\times{p}+1,代码写出来就是 int(log10(2)*p+1)。

#include<bits/stdc++.h>
#define re register
using namespace std;
int P,lena,lenb,ans;
int a[505],b[505];
void print(int x){
    if(x>9) print(x/10);
    putchar(x%10+'0');
}
void mul(int a[],int b[]){
    int c[2000]={0};
    lena=lenb=499;
    for(int i=499;i>=0;i--) if(a[i]!=0){lena=i;break;}
    for(int i=499;i>=0;i--) if(b[i]!=0){lenb=i;break;}
    for(re int i=0;i<=lena;i++)
        for(re int j=0;j<=lenb;++j){
            c[i+j+1]+=a[i]*b[j]/10;
            c[i+j]+=a[i]*b[j]%10;
        }
    for(re int i=0;i<=499;++i){
        c[i+1]+=c[i]/10;
        c[i]%=10;
    }
    for(re int i=499;i>=0;--i)
        a[i]=c[i];
}
int main(){
    a[0]=1,b[0]=2;
    cin>>P;
    printf("%d\n",int(log10(2)*P+1));
    for(;P;P>>=1,mul(b,b)) if(P&1) mul(a,b);
    a[0]-=1;
    for(int h=1;h<=10;++h){
        for(int i=499-(h-1)*50;i>=(500-h*50);i--)
            putchar(a[i]+48);
        putchar('\n');
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/g21wcr/article/details/83373806
今日推荐