50分求解

P1045 [NOIP2003 普及组] 麦森数

hjbaoyx @ 2023-07-25 09:48:16

#include <bits/stdc++.h> 

using namespace std;

int a[10010];

int main( ) {
    int p,k;
    scanf("%d",&p);
    a[1]=1;
    for(int i=1;i<=p;i++) {
        k=0;
        for(int j=1;j<=10000;j++) {
            a[j]=a[j]*2+k;
            k=a[j]/10;
            a[j]%=10;
        }
    }
    a[1]-=1;
    k=10000;
    while(a[k]==0&&k>1) k--;
    printf("%d",k);
    for(int i=500;i>=1;i--) {
        if(i%50==0) printf("\n");
        printf("%d",a[i]);
    }
    return 0;
}

by Life_passing_by @ 2023-07-25 10:23:49

@baoyexuan 高精压位计算,一次求解60次幂,然后再计算进位,对于位数可以数学求解,所以只用计算后500位的内容(位数=log10(2)*p+1,详见题解一)

#include <bits/stdc++.h>
using namespace std;
unsigned long long a[510];
long long N;
int main()
{
    cin >> N;
    cout<<(long long)(log10(2)*N+1)<<endl;
    a[500]=2;
    N--; 
    for(;N>0;N-=60){
        for(int i=500;i>0;i--)(N>60?(a[i]<<=60):(a[i]<<=N));
        for(int i=500;i>0;i--)if(a[i]>=10)a[i-1]+=a[i]/10,a[i]%=10;
    }
    a[500]--;
    for(int i=0;i<=9;i++){
        for(int j=1;j<=50;j++)cout<<a[i*50+j];
        cout<<endl;
    }
    return 0;
}

by hjbaoyx @ 2023-08-01 15:41:46

@Life_passing_by 谢谢


|