求优化,五十分TLE

P1045 [NOIP2003 普及组] 麦森数

protractor @ 2023-07-22 23:07:40

#include<iostream>
using namespace std;
int m[1000050]={0,1},ml=1;
int main()
{
    int p;
    cin>>p;
    for(int i=1;i<=p;i++)
    {
        for(int j=1;j<=ml;j++) m[j]*=2;
        for(int j=1;j<=ml;j++)
        {
            m[j+1]+=m[j]/10;
            m[j]%=10;
        }
        while(m[ml])
        {
            m[ml+1]+=m[ml]/10;
            m[ml]%=10;
            ml++;
        }
    }
    while(m[ml]==0) ml--;
    m[1]--;//2的p次幂一定不是5的倍数,所以也不会是10的倍数,末尾没有0,不考虑退位的问题; 
    cout<<ml<<'\n';
    for(int i=10;i>=1;i--) 
    {
        for(int j=50;j>=1;j--) cout<<m[(i-1)*50+j];
        cout<<'\n';
    }
    return 0;
}

by Life_passing_by @ 2023-07-25 09:21:06

@lijinhan_bmx 压位优化,一次计算60次幂然后统一进位

#include<bits/stdc++.h>
using namespace std;
unsigned long long m[510];
int main()
{
    long long p;
    cin>>p;
    cout<<(long long)(log10(2)*p+1)<<endl;
    m[1]=2;
    p--;
    for(;p>0;p-=60)
    {
        for(int j=1;j<=500;j++) (p>60?(m[j]<<=60):(m[j]<<=p));
        for(int j=1;j<=500;j++)if(m[j]>=10)m[j+1]+=m[j]/10,m[j]%=10;
    }
    m[1]--;//2的p次幂一定不是5的倍数,所以也不会是10的倍数,末尾没有0,不考虑退位的问题; 
    for(int i=9;i>=0;i--) 
    {
        for(int j=50;j>0;j--) cout<<m[i*50+j];
        cout<<'\n';
    }
    return 0;
}

AC


by Life_passing_by @ 2023-07-25 09:22:26

@lijinhan_bmx 前面的计算位数是一个高中数学知识的推导,不懂的话可以学一下对数然后看第一篇题解


by protractor @ 2023-07-25 12:49:19

@Life_passing_by 谢谢


|