bzoj1089: [SCOI2003]严格n元树

传送门
设f[i]表示深度小于等于i的树的个数。
得到公式
f[i]=f[i-1]^n+1
答案就是f[d]-f[d-1];
高精度水过。

type arr=array [0..5005] of int64;
var
  f:array [0..20] of arr;
  n,d,i:longint;
procedure cheng(a,b:arr; var c:arr);
  var i,j:longint; x:int64;
  begin
    fillchar(c,sizeof(c),0);
    for i:=1 to a[0] do begin
      x:=0;
      for j:=1 to b[0] do begin
        x:=c[i+j-1]+x+a[i]*b[j];
        c[i+j-1]:=x mod 100000000;
        x:=x div 100000000;
      end;
      c[i+b[0]]:=x;
    end;
    if (c[a[0]+b[0]]<>0) then c[0]:=a[0]+b[0] else c[0]:=a[0]+b[0]-1;
  end;
procedure mi(x:longint);
  begin
    if (x=1) then exit;
    mi(x div 2);
    cheng(f[i],f[i],f[i]);
    if x mod 2=1 then cheng(f[i],f[i-1],f[i]);
    exit;
  end;
procedure jiayi;
  var j:longint;
  begin
    inc(f[i,1]);
    for j:=1 to f[i,0] do begin
      inc(f[i,j+1],f[i,j] div 100000000); f[i,j]:=f[i,j] mod 100000000;
    end;
    if (f[i,f[i,0]+1]<>0) then inc(f[i,0]);
  end;
procedure jian;
  var i:longint;
  begin
    for i:=1 to f[d,0] do f[d,i]:=f[d,i]-f[d-1,i];
    for i:=1 to f[d,0] do
      if f[d,i]<0 then begin inc(f[d,i],100000000); dec(f[d,i+1]); end;
    while (f[d,0]<>1) and (f[d,f[d,0]]=0) do dec(f[d,0]);
  end;
procedure print;
  var i:longint;
  begin
    write(f[d,f[d,0]]);
    for i:=f[d,0]-1 downto 1 do begin
      if f[d,i]<10000000 then write(0);
      if f[d,i]<1000000 then write(0);
      if f[d,i]<100000 then write(0);
      if f[d,i]<10000 then write(0);
      if f[d,i]<1000 then write(0);
      if f[d,i]<100 then write(0);
      if f[d,i]<10 then write(0);
      write(f[d,i]);
    end;
  end;
begin
  read(n,d);
  if d=0 then begin write(1); exit; end;
  f[0,0]:=1; f[0,1]:=1;
  for i:=1 to d do begin
    f[i]:=f[i-1];
    mi(n);
    jiayi;
  end;
  jian;
  print;
end.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值