bzoj1833: [ZJOI2010]count 数字计数

传送门
按照老规矩,我们要将其变为两个(1,l-1),(1,r)的询问。
然后,我们按位枚举,将肯定小于边界的统计进去。
然后这样我们九确定了接下来枚举数字的第1位数字
依次推下去九可以了。

uses math;
var
  c,d,e,f:array [0..20] of int64;
  a,b,p,i:int64;
  j,k,l:longint;
procedure cf(x:int64);
  begin
    fillchar(d,sizeof(d),0);
    while (x<>0) do begin inc(d[x mod 10]); x:=x div 10; end;
  end;
procedure make(x,y,k:int64);
  var i,j:longint;
  begin
    cf(x);
    for i:=0 to y-1 do
      begin
        inc(c[i],e[k]);
        for j:=0 to 9 do c[j]:=c[j]+d[j]*e[k];
        for j:=0 to 9 do c[j]:=c[j]+(k-1)*e[k-1];
      end;
  end;
begin
  e[1]:=1;
  for j:=2 to 15 do e[j]:=e[j-1]*10;
  read(a,b);
  dec(a);
  i:=1; p:=1;
  while (a>=1) do
    begin
      make(a div 10,a mod 10,i);
      inc(c[a mod 10]);
      a:=a div 10; p:=p*10; inc(i);
      dec(c[0],p div 10);
    end;
  f:=c;
  fillchar(c,sizeof(c),0);
  i:=1; p:=1;
  while (b>=1) do
    begin
      make(b div 10,b mod 10,i);
      inc(c[b mod 10]);
      b:=b div 10; p:=p*10; inc(i);
      dec(c[0],p div 10);
    end;
  for j:=0 to 8 do write(c[j]-f[j],' ');
  write(c[9]-f[9]);
end.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值