You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

61 lines
2.0 KiB

2 years ago
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
using namespace std;
typedef long long LL;
const int N = 20;
/*
x,y <= 10^{18},10a,20
使32使f
32*32*10010=10250240 byte = 10010 kb = 9.775390625 mb
65535kb=64mb
C++64MB
*/
LL a[N];
/*
pos:N=20
k:120
sum:,209
10*20+10*19+....+10*1=10*(1+2+3+...+20)=10*21*10=2100
*/
LL f[N][N][2110];
LL dfs(int pos, int k, int sum, bool lead, bool limit) {
if (pos == 0) return sum == 0;
if (sum < 0) return 0;
if (!lead && !limit && ~f[pos][k][sum]) return f[pos][k][sum];
int up = limit ? a[pos] : 9;
LL ans = 0;
for (int i = 0; i <= up; i++)
// sum + (pos - k) * i : 这句话很牛Xpos > k 是加pos < k是减
ans += dfs(pos - 1, k, sum + (pos - k) * i, lead && i == 0, limit && i == a[pos]);
if (!limit && !lead) return f[pos][k][sum] = ans;
return ans;
}
LL calc(LL x) {
if (x == -1) return 0; //如果输入的是l=0,则返回0
int al = 0;
while (x) a[++al] = x % 10, x /= 10;
LL ans = 0;
for (int i = al; i; i--) //枚举每一个数位模拟此位置k为平衡数位
ans += dfs(al, i, 0, true, true);
// 00,000,0000......
return ans - al + 1;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
//平衡数是数的本身性质,与给定的区间无关,可以将memset放在循环外初始化
memset(f, -1, sizeof f);
int T;
cin >> T;
LL l, r;
while (T--) {
cin >> l >> r;
printf("%lld\n", calc(r) - calc(l - 1));
}
return 0;
}