算法训练 麦森数
时间限制: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
题意: 略
分析: 主要是那个 2p−1 2 p − 1 稍微分析可知,当p > 1000时,它的位数和加一减一都不会变,所以我们只要对结果取一下 lg(res) l g ( r e s ) 即可,换算下可以求出 lg(2p)=p∗lg(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