首页 > 代码库 > 2003麦森数

2003麦森数

题目描述 Description

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

任务:从文件中输入P(1000<P<3100000),计算2P-1的位数和最后500位数字(用十进制高精度数表示)

输入描述 Input Description

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

输出描述 Output Description

第一行:十进制高精度数2P-1的位数。

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

不必验证2P-1与P是否为素数。

样例输入 Sample Input

1279

样例输出 Sample Output

386

00000000000000000000000000000000000000000000000000

00000000000000000000000000000000000000000000000000

00000000000000104079321946643990819252403273640855

38615262247266704805319112350403608059673360298012

23944173232418484242161395428100779138356624832346

49081399066056773207629241295093892203457731833496

61583550472959420547689811211693677147548478866962

50138443826029173234888531116082853841658502825560

46662248318909188018470682222031405210266984354887

32958028878050869736186900714720710555703168729087

数据范围及提示 Data Size & Hint
 
 
 

题解:

高精度+数论+二分。

运用公式:2(y)=sqr(2(y div 2)),如果y是偶数就不用管了,如果y是奇数,就再乘2。求位数的公式(2(y)):trunc(log10(2)*y)+1(log10函数在math数学库里有的)。

uses math;

var i,p:longint;

    a,c:array[0..2001]of longint;

procedure f(k:longint);

var i,j:longint;

 begin

  if k=0 then exit;

  f(k div 2);

  fillchar(c,sizeof(c),0);

  for i:=1 to a[0] do

   for j:=1 to a[0] do

    begin

     inc(c[i+j-1],c[i+j-2] div 10+a[i]*a[j]);

     c[i+j-2]:=c[i+j-2] mod 10;

    end;

  c[0]:=a[0]*2-1;

  while c[c[0]]>9 do

   begin

    c[c[0]+1]:=c[c[0]] div 10;

    c[c[0]]:=c[c[0]] mod 10;

    inc(c[0]);

   end;

  a:=c;

  if c[0]>500 then a[0]:=500;

  if k mod 2=0 then exit;

  fillchar(c,sizeof(c),0);

  for i:=1 to a[0] do

   begin

    c[i]:=a[i]*2+c[i-1] div 10;

    c[i-1]:=c[i-1] mod 10;

   end;

  c[0]:=a[0];

  while c[c[0]]>9 do

   begin

    c[c[0]+1]:=c[c[0]] div 10;

    c[c[0]]:=c[c[0]] mod 10;

    inc(c[0]);

   end;

  a:=c;

  if c[0]>500 then a[0]:=500;

 end;

begin

 readln(p);

 writeln(trunc(log10(2)*p)+1);

 a[0]:=1;

 a[1]:=1;

 f(p);

 dec(a[1]);

 for i:=500 downto 1 do

  if (i mod 50=1) then writeln(a[i])

                  else write(a[i]);

end.

2003麦森数