分治 麦森数

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.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值