Codevs_P2123 麦森数2

14 篇文章 0 订阅
7 篇文章 0 订阅

题目描述 Description
形如2P-1的素数称为麦森数, 这时P一定也是个素数. 但反过来不一定, 即如果P是个素数, 2P-1不一定也是素数. 在1998年底, 人们找到了37个麦森数. 当时最大的一个是P=3021377, 它有909526位. 但是截止到2013年2月, 美国中央密苏里大学数学家库珀领导的研究小组通过参加一个名为“互联网梅森素数大搜索”(GIMPS)项目, 日前发现了第48个梅森素数——P=57885161; 该素数也是目前已知的最大素数, 有17425170位. 如果用普通字号将它连续打印下来, 它的长度可超过65公里! 美国数学学会发言人布林说:“超大素数令数学家和计算机科学家感到兴奋.” 他认为这是素数探究的一项重大突破. 麦森数有许多重要应用, 它与完全数密切相关. 所以, 给出一个P, 请计算出2P-1.

输入描述 Input Description
一个整数P.

输出描述 Output Description
第一行: 十进制高精度数2P-1的位数.
第2-21行: 十进制高精度数2P-1的最后1000位数字. (每行输出50位, 共输出10行, 不足500位时高位补0)

样例输入 Sample Input
1279

样例输出 Sample Output
386
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000104079321946643990819252403273640855
38615262247266704805319112350403608059673360298012
23944173232418484242161395428100779138356624832346
49081399066056773207629241295093892203457731833496
61583550472959420547689811211693677147548478866962
50138443826029173234888531116082853841658502825560
46662248318909188018470682222031405210266984354887
32958028878050869736186900714720710555703168729087

数据范围及提示 Data Size & Hint
1000≤P<2147483647

cout输出辣么大的整数会用指数形式 所以限制一下长度
头文件 setprecision()
分治+快速幂

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<iomanip>
using namespace std;
int p,k;
int a[1005],b[2005];
void print(){
    cout<<setprecision(16)<<floor(log(2)/log(10)*p+1)<<endl;
    for(int i=1000;i>0;i--) {
        printf("%d",a[i]);
        if((i-1)%50==0) printf("\n");
    }
}
void work(int x){
    if(x==0) return;
    work(x/2);
    memset(b,0,sizeof(b));
    for(int i=1;i<=1000;i++)
        for(int j=1;j<=1000;j++){
            if(x%2==0)
                b[i+j-1]+=a[i]*a[j];
            else b[i+j-1]+=a[i]*a[j]*2;
        }
    for(int i=1;i<=1000;i++){
        a[i]=b[i]%10;
        b[i+1]+=b[i]/10;
    }
}
void cut(){
    a[1]--;int i=1;
    while(a[i]<0) a[i+1]--,a[i]+=10,i++;
}
int main(){
    scanf("%d",&p);
    a[1]=1;work(p);
    cut();
    print();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值