专栏文章

题解:P1045 [NOIP 2003 普及组] 麦森数

P1045题解参与者 2已保存评论 1

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
1 条
当前快照
1 份
快照标识符
@mip1nlar
此快照首次捕获于
2025/12/03 04:42
3 个月前
此快照最后确认于
2025/12/03 04:42
3 个月前
查看原文
提供封装结构体的高精快速幂板子。

Solution

第一问求的是 log10(2p1)=plog102\lceil\log_{10}{(2^p-1)}\rceil=\lceil p \log_{10}{2}\rceil,直接输出。
对于第二问,我们使用快速幂。需要实现 500500 位的高精乘高精,过程中保留后 500500 位即可。
重点在代码。

Code

CPP
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=510;

struct Bignum   //养成好习惯
{
    int val[N],len;
    void init()
    {
        memset(val,0,sizeof(val));
        len=0;
    }
    Bignum operator *(const Bignum &x)const
    {
        Bignum res;
        res.init();
        res.len=min(len+x.len,500ll);
        for(int i=0;i<len;i++)
            for(int j=0;j<x.len&&i+j<500;j++)
                res.val[i+j]+=val[i]*x.val[j];
        for(int i=0;i<res.len;i++)
        {
            if(res.val[i]>=10)
            {
                res.val[i+1]+=res.val[i]/10;
                res.val[i]%=10;
            }
        }
        while(res.val[res.len]&&res.len+1<500)
        {
            if(res.val[res.len]>=10)
            {
                res.val[res.len+1]+=res.val[res.len]/10;
                res.val[res.len]%=10;
            }
            res.len++;
        }
        res.val[res.len]=0;
        return res;
    }
    void print()
    {
        val[0]--;     //末位显然不可能是 0,减 1 即可
        for(int i=499;i>=0;i--)
        {
            cout<<val[i];
            if(i%50==0)cout<<"\n";
        }
    }
};

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int p;
    cin>>p;
    cout<<ceil(p*log10(2))<<"\n";
    Bignum ji,base;
    ji.len=base.len=1;
    ji.val[0]=1,base.val[0]=2;
    while(p)
    {
        if(p&1)ji=ji*base;
        base=base*base;
        p>>=1;
    }
    ji.print();
    return 0;
}

评论

1 条评论,欢迎与作者交流。

正在加载评论...