SSL 1030
洛谷 P1045 麦森数
题目描述
形如2^P-1的素数称为麦森数,这时P一定也是个素数。但反过来不一定,即如果P是个素数,2^P-1不一定也是素数。到1998年底,人们已找到了37个麦森数。最大的一个是P=3021377,它有909526位。麦森数有许多重要应用,它与完全数密切相关。
任务:从文件中输入P(1000<P<3100000),计算2^P-1的位数和最后500位数字(用十进制高精度数表示)
题目分析
可以用分治解决,不过必须要用高精度计算。
分治法同取余,请自行转:
http://blog.csdn.net/SSL_QYH0Ice/article/details/53697764
程序
type
arr=array[1..1000]of longint;
var
p,i,j,o:longint;
k:array[1..500]of longint;
a,b,c:arr;
procedure pre(n:longint);
begin
if n=0 then exit;
inc(i);
k[i]:=n mod 2;
pre(n div 2);
end;
procedure main;
var
i,j:longint;
begin
for i:=1 to 500 do
for j:=1 to 500 do
begin
c[i+j-1]:=c[i+j-1]+a[i]*b[j];
c[i+j]:=c[i+j]+c[i+j-1] div 10;
c[i+j-1]:=c[i+j-1] mod 10;
end;
end;
procedure sub;
var
g,i:longint;
begin
g:=0;
for i:=500 downto 1 do
begin
if a[i]>=b[i]+g then
begin
a[i]:=a[i]-b[i]-g;
g:=0;
end
else
begin
a[i]:=10+a[i]-b[i]-g;
g:=1;
end;
end;
end;
begin
readln(p);
i:=0;
pre(p);
a[1]:=1;
for j:=i downto 1 do
begin
fillchar(c,sizeof(c),#0);
b:=a;
main;
a:=c;
if k[j]=1 then
begin
fillchar(c,sizeof(c),#0);
fillchar(b,sizeof(b),#0);
b[1]:=2;
main;
a:=c;
end;
end;
b[1]:=1;
sub;
o:=trunc(p*(ln(2)/ln(10))+1);
writeln(o);
for i:=500 downto 1 do
write(a[i]);
end.