1833: [ZJOI2010]count 数字计数 - BZOJ

Description
给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码(digit)各出现了多少次。
Input
输入文件中仅包含一行两个整数a、b,含义如上所述。
Output
输出文件中包含一行10个整数,分别表示0-9在[a,b]中出现了多少次。
Sample Input
1 99
Sample Output
9 20 20 20 20 20 20 20 20 20
HINT

30%的数据中,a<=b<=10^6;
100%的数据中,a<=b<=10^12。

 

首先把这个问题变成f(b)-f(a-1)

然后就是比较简单的数位dp

f[i,j]表示长度为i以j开头0到9各个数字的出现次数

先算出全部的,再减去不合法的

不合法的就是枚举,减去从第i位开始超出n的情况,注意减去比第i位更高的数字(一开始就这样WA的)

 1 type

 2         node=array[0..9]of int64;

 3 var

 4         f:array[0..15,0..9]of node;

 5         ten:array[0..15]of int64;

 6         a,b:int64;

 7 

 8 operator +(a,b:node)c:node;

 9 var

10         i:longint;

11 begin

12         for i:=0 to 9 do

13           c[i]:=a[i]+b[i];

14 end;

15 

16 operator -(a,b:node)c:node;

17 var

18         i:longint;

19 begin

20         for i:=0 to 9 do

21           c[i]:=a[i]-b[i];

22 end;

23 

24 operator *(a:node;b:int64)c:node;

25 var

26         i:longint;

27 begin

28         for i:=0 to 9 do

29           c[i]:=a[i]*b;

30 end;

31 

32 function ff(x:int64):node;

33 var

34         s:array[0..15]of longint;

35         i,j,len:longint;

36         fff:node;

37 begin

38         fillchar(ff,sizeof(ff),0);

39         fillchar(fff,sizeof(fff),0);

40         for i:=1 to 13 do

41           begin

42             s[i]:=x mod 10;

43             x:=x div 10;

44           end;

45         for i:=13 downto 1 do

46           if s[i]<>0 then break;

47         len:=i;

48         for i:=1 to len do

49           for j:=1 to 9 do

50             ff:=ff+f[i,j];

51         for i:=len downto 1 do

52           begin

53             for j:=s[i]+1 to 9 do

54               ff:=ff-f[i,j]-fff*ten[i];

55             inc(fff[s[i]]);

56           end;

57 end;

58 

59 procedure print(a:node);

60 var

61         i:longint;

62 begin

63         for i:=0 to 8 do

64           write(a[i],' ');

65         write(a[9]);

66 end;

67 

68 procedure main;

69 var

70         i,j,k:longint;

71 begin

72         read(a,b);

73         ten[1]:=1;

74         for i:=2 to 13 do

75           ten[i]:=ten[i-1]*10;

76         for i:=1 to 13 do

77           for j:=0 to 9 do

78             begin

79               for k:=0 to 9 do

80                 f[i,j]:=f[i,j]+f[i-1,k];

81               inc(f[i,j,j],ten[i]);

82             end;

83         print(ff(b)-ff(a-1));

84 end;

85 

86 begin

87         main;

88 end.
View Code

 

你可能感兴趣的:(count)