蓝桥杯 算法训练 麦森数 【大数取模】

算法训练 麦森数

时间限制:1.0s 内存限制:256.0MB

问题描述

  形如2P-1的素数称为麦森数,这时P一定也是个素数。但反过来不一定,即如果P是个素数,2P-1不一定也是素数。到1998年底,人们已找到了37个麦森数。最大的一个是P=3021377,它有909526位。麦森数有许多重要应用,它与完全数密切相关。
  任务:从文件中输入P(1000

输入格式

  文件中只包含一个整数P(1000

输出格式

  第一行:十进制高精度数2P-1的位数。
  第2-11行:十进制高精度数2P-1的最后500位数字。(每行输出50位,共输出10行,不足500位时高位补0)
  不必验证2P-1与P是否为素数。

样例输入

1279

样例输出

386
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000104079321946643990819252403273640855
38615262247266704805319112350403608059673360298012
23944173232418484242161395428100779138356624832346
49081399066056773207629241295093892203457731833496
61583550472959420547689811211693677147548478866962
50138443826029173234888531116082853841658502825560
46662248318909188018470682222031405210266984354887
32958028878050869736186900714720710555703168729087

题意: 略

分析: 主要是那个 2p1 2 p − 1 稍微分析可知,当p > 1000时,它的位数和加一减一都不会变,所以我们只要对结果取一下 lg(res) l g ( r e s ) 即可,换算下可以求出 lg(2p)=plg(2) l g ( 2 p ) = p ∗ l g ( 2 ) ,然后就是简单的快速幂取模了,不解释了

参考代码

import java.math.*;
import java.util.Scanner;

public class Main {
    public static  void main(String args[]) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int ans = (int) (n * Math.log10(2.0)) + 1;
        BigInteger res = quick_pow(BigInteger.valueOf(2),n);
        res = res.subtract(BigInteger.valueOf(1));
        System.out.println(ans);
        String s = res.toString();
        if(s.length() < 500) {
            int len = s.length();
            for(int i = 0;i < 500 - len;i++) {
                s = '0' + s;
            }
        }
        for(int i = 0;i < s.length();i++) {
            if(i % 50 == 0 && i > 0) System.out.println();
            System.out.print(s.charAt(i));
        }
    }
    static  BigInteger quick_pow(BigInteger a,int b) {
        BigInteger res = BigInteger.ONE;
        BigInteger Mod = BigInteger.valueOf(10).pow(500);
        while (b > 0) {
            if(b % 2 == 1) {
                res = res.multiply(a).mod(Mod);
            }
            a = a.multiply(a).mod(Mod);
            b /= 2;
        }
        return  res;
    }
}
  • 如有错误或遗漏,请私聊下UP,thx
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值