Description
一天,小R準備找小h去游泳,當他找到小h時,發現小h正在痛苦地寫着一列數,1,2,3,…n,於是就問小h痛苦的原因,小h告訴他,現在他要算1..n這些數裏面,1出現的次數是多少,如n=11的時候,有1,10,11共出現4次1,現在給出n,你能快速給出答案麼?
Input
一行,就是n,(1<=n<=maxlongint)
Output
一個整數,表示1..n中1出現的次數。
Sample Input
11
Sample Output
4
討論
看數據範圍就知道o(n)是不現實的,對於n中第x位的數字,分三類處理(只找1的個數):
(1)爲0時,那麼貢獻就是n div 10^x*10^(x-1)
循環的次數 * 每次循環的貢獻
(2)爲1時,(1)+n mod 10^(x-1)+1
在額外的循環中出現的次數
(3) >1時,[(n div 10^x)+1]*10^(x-1)
和(1)相比循環多了1次
var
i:longint;
ans,n:int64;
f:array[0..12] of int64;
s:string;
begin
readln(s);
val(s,n);
f[length(s)]:=1;
for i:=length(s)-1 downto 1 do
f[i]:=f[i+1]*10;
for i:=1 to length(s) do
begin
if i<>1 then
if s[i]='1' then
ans:=ans+n div f[i-1]*f[i]+n mod f[i]+1
else
if s[i]>'1' then
ans:=ans+((n div f[i-1])+1)*f[i]
else
ans:=ans+n div f[i-1]*f[i]
else
if s[i]='1' then
ans:=ans+n mod f[i]+1
else
ans:=ans+f[i];
end;
writeln(ans);
end.