# sgu258 Almost Lucky Numbers （数位dp）

## tip：

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long LL;
LL l,r,n;
int num[20],a[20];
LL dp0[10][10*9][10][10],F[20];///前i位和为j 最小为p 最大是q  的方案数
LL dp1[10][10*9][10][10];

void _dp0(string s){
for(int i = 0 ; i < n ; i++){
for(int j = 0 ; j <= 9*n ; j++){
for(int p = 0 ; p <= 9 ; p++){
for(int q = 0 ; q <= 9 ; q++){
dp0[i][j][p][q] = 0;
}
}
}
}
if(s[1]=='*'){
for(int i = 0;i <= 9;i++)   dp0[1][s[0]-'0'+i][i][i] = 1;
}
else
dp0[1][s[0]-'0'+s[1]-'0'][s[1]-'0'][s[1]-'0'] = 1;
int mk = 1;
for(int i = mk ; i < n ; i++){
for(int j = 0 ; j <= 9*n ; j++){
for(int p = 0 ; p <= 9 ; p++){
for(int q = 0 ; q <=  9 ; q++){
if(dp0[i][j][p][q] > 0){
if(s[i+1] == '*'){
for(int k = 0 ; k <= 9 ; k ++){
dp0[i+1][j+k][min(p,k)][max(q,k)] += dp0[i][j][p][q];
}
}
else{
int tmp = s[i+1]-'0';
dp0[i+1][j+tmp][min(p,tmp)][max(q,tmp)] += dp0[i][j][p][q];
}
}
}
}
}
}
}
void _dp1(string s){
for(int i = 0 ; i < n ; i++){
for(int j = 0 ; j <= 9*n ; j++){
for(int p = 0 ; p <= 9 ; p++){
for(int q = 0 ; q <= 9 ; q++){
dp1[i][j][p][q] = 0;
}
}
}
}
if(s[0]=='*'){
for(int i = 0;i <= 9; i++)   dp1[0][i][i][i] = 1;
//cout <<"a  a"<<endl;
}
else{
dp1[0][s[0]-'0'][s[0]-'0'][s[0]-'0'] = 1;
//cout <<"aaaaaaaa"<<endl;
}
int mk = 0;
//cout <<"n = "<<n<<endl;
for(int i = mk ; i < n-1 ; i++){
for(int j = 0 ; j <= 9*n ; j++){
for(int p = 0 ; p <= 9 ; p++){///最小
for(int q = 0 ; q <=  9 ; q++){///最大
if(dp1[i][j][p][q] == 0)    continue;
//cout <<"  ss   "<<endl;
if(s[i+1] == '*'){
for(int k = 0 ; k <= 9 ; k ++){
dp1[i+1][j+k][min(p,k)][max(q,k)] += dp1[i][j][p][q];
}
}
else{
int tmp = s[i+1]-'0';
dp1[i+1][j+tmp][min(p,tmp)][max(q,tmp)] += dp1[i][j][p][q];
}
}
}
}
}
}
LL check(string s){
//cout <<s<<endl;
if(s.size() == 2){
if(s[1] == '*') return 9;
else{
if(s[0] == s[1])    return 0;
return 1;
}
}
string s0 = "",s1 = "";
n = s.size()/2;
for(int i = 0 ; i < n ; i++)    s0.push_back(s[i]);
for(int i = 0 ; i < n ; i++)    s1.push_back(s[i+n]);
_dp0(s0);
_dp1(s1);

LL ans = 0;
for(int sum0 = 0 ; sum0 <= 9*n ; sum0++){
for(int p0 = 0 ; p0 <= 9 ; p0++){
for(int q0 = 0 ; q0 <= 9 ; q0++){
if(dp0[n-1][sum0][p0][q0] == 0) continue;
for(int sum1 = 0 ; sum1 <= 9*n ;sum1++){
if(sum1 == sum0)    continue;
//cout <<"sum1 = "<<sum1<<endl;
for(int p1 = 0 ; p1 <= 9 ; p1 ++){
for(int q1 = 0 ;q1 <= 9 ; q1++){
if(dp1[n-1][sum1][p1][q1] == 0 ) continue;///min: -max+0     max: -min+9
//cout <<"bb = "<<endl;
if( ((min(sum0-q0+0,sum0+1-(s[0]-'0')) <= sum1) && (max(sum0+9-p0,sum0+9-(s[0]-'0')) >= sum1) )||
((    sum1-q1+0                    <= sum0) && (    sum1+9-p1                    >= sum0) )){
//cout <<"hah"<<endl;
ans += dp0[n-1][sum0][p0][q0]*dp1[n-1][sum1][p1][q1];
}
}
}
}
}
}
}
//cout <<"ans    - >   "<<ans<<endl;
return ans;
}
LL getnum(int cnt){
string s0 = "",s1 = "";
LL ans= 0;
for(int t = cnt ; t >= 1; t--){
int d = num[t];
for(int i =  (t == cnt?1:0) ; i < d ;  i++){
s1 = s0;
s1.push_back('0'+i);
for(int j = t-1;j >= 1;j--) s1.push_back('*');
ans += check(s1);
}
s0.push_back('0'+d);
}
return ans;
}
LL sov(int k){
if(k < 10)  return 0;
int cnt = 0,tmp = k;
LL ans = 0;
memset(num,0,sizeof(num));
while(tmp > 0){
num[++cnt] = tmp%10;
tmp /= 10;
}
for(int i = 2 ; i < cnt ;i+=2)
ans += F[i];
if((cnt&1) || k == 0){
return ans;
}
ans += getnum(cnt);
return ans;
}
int main(){
F[2]=81;F[4]=7389;F[6]=676133;F[8]=62563644;
while(cin >> l >>r)
cout <<sov(r+1)-sov(l)<<endl;
}
//1200 1210