fzoj 2113数位dp
参考http://blog.csdn.net/xingyeyongheng/article/details/8785785
#include<stdio.h>
#define ll long long
#define N 20
ll dp[N];//dp[N]记录长度为i的一的个数
ll power(ll a) {
ll sum=1,i;
for(i=1;i<=a;i++)
sum*=10;
return sum;
}
void init() {
ll i;
dp[1]=1;
for(i=2;i<=19;i++)
dp[i]=dp[i-1]*10+power(i-1);//长度为i-1的的1的个数前面加上任意的一个数也一定含有一,在加上首项为1的任意数
}
ll slove(ll x) {
ll to=0,i,k=0,a[N],flag=0;
while(x) {
a[++k]=x%10;
x/=10;
}
a[k+1]=0;
for(i=k;i>=1;i--) {
to=to+a[i]*dp[i-1];//记录有几个长度为i-1的数
if(flag)to=to+a[i]*flag*power(i-1);//如果前面已经有1了就把后面的任意数都算进去
if(a[i]>1)to=to+power(i-1);//如果大于1那么就有以1开头的任意数也要算进去
if(a[i]==1)flag++;//记录前面1的个数
}
return to;
}
int main() {
ll a,b;
init();
while(scanf("%I64d%I64d",&a,&b)!=EOF) {
printf("%I64d\n",slove(b+1)-slove(a));
}
return 0;
}