[NOIP2003]麦森数

  题目描述

形如2^p-1的素数称为麦森数,这时p一定也是个素数。但反过来不一定,即如果p是个素数,2^p-1不一定也是素数。 到1998年底,人们已找到了37个麦森数。最大的一个是p=3021377,它有909526位。 麦森数有许多重要应用,它与完全数密切相关。 现要求输入p(1000< P < 3100000),计算2^p-1的位数和最后500位数字(用十进制高精度数表示)。

   输入

第1行:1个整数p(1000<p<3100000)< div="">
输出
第1行:十进制高精度数2^p-1的位数; 第2..11行:十进制高精度数2^p-1的最后500位数字(每行输出50位,共输出10行,不足500位时高位补0); 注意:不必验证2^p-1与p是否为素数。

样例输入

 (如果复制到控制台无换行,可以先粘贴到文本编辑器,再复制)

1279

样例输出

       
       
386
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
38615262247266704805319112350403608059673360298012
00000000000000104079321946643990819252403273640855
23944173232418484242161395428100779138356624832346
50138443826029173234888531116082853841658502825560
49081399066056773207629241295093892203457731833496 61583550472959420547689811211693677147548478866962 46662248318909188018470682222031405210266984354887
32958028878050869736186900714720710555703168729087

    分析: 重定义运算符+快速幂
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#define LL long long
using namespace std;
//#define BIG 100000LL
const LL BIG=100000LL; 
struct INT{
    LL data[500];
    int len;
    INT(){memset(data,0,sizeof(data));len=0;}
    void operator=(int x){
        while(x){
            data[len++]=x%BIG;
            x/=BIG;
        }
    }
}ans,tmp;
int p;
INT operator*(const INT &a,const INT &b){
    INT ret; 
    int i, j, add; 
    for(i=0;i<a.len&&i<100;i++){
        add=0;
        for(j=0;j<b.len&&j<100;j++)
            if(i+j<100){
                ret.data[i+j]+=a.data[i]*b.data[j]+add;
                if((add=ret.data[i+j]/BIG))
                    ret.data[i+j]%=BIG;
            }
        if(i+j<100)
            ret.data[i+j]+=add;
    }
    int len=i+j-1;
    if(add&&len<100)
        ret.data[len++]=add;
    ret.len=len;
    return ret;
}
void work(){
    int t=p;
    ans=1;tmp=2;
    while(t){
        if(t&1)ans=ans*tmp;
        t>>=1;
        tmp=tmp*tmp;
    }
}
int main(){
    int i;
    scanf("%d",&p);
    printf("%d\n",int(log10(2)*p)+1);
    work();
    ans.data[0]--;
    for(i=99;i>=0;i--){
        printf("%05lld",ans.data[i]);
        if(i%10==0)
            printf("\n");
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值