Description
Given two numbers \ (a, ~ b \) obtaining \ ([a ~, b] \) in the sum of the digits of the number divisible by the number of the original number.
Limitations
\ (1 \ leq a, ~ b \ leq 10 ^ {18} \)
Solution
Consider digital DP.
Provided digital \ (A = \ sum_ I = {0} a_i ^ K \ Times 10 ^ I \) , and its digital \ (B = \ sum_ {i = 0} ^ k a_i \)
Then \ (A \) satisfies the condition is the \ (A \ equiv 0 \ PMOD B \) , depending on the nature of congruence can be disassembled summation symbol:
\[\sum_{i = 0}^k (a_i \times 10^i \bmod B)~\equiv~0\pmod B\]
Consider \ (B \) in fact very small, \ (18 \) digits are \ (9 \) when no more than \ (200 \) , so you can enumerate \ (B \) .
Set \ (f_ {i, j, k} \) anterior considered \ (I \) bits, the first \ (I \) bits corresponding to the analog \ (B \) values \ (J \) , and followed by several numbers and as \ (\ k) , not on top of the world program number when transferring enumerate the current one is that a few can.
Code
// luogu-judger-enable-o2
#include <cstdio>
#include <cstring>
const int maxn = 70;
const int maxm = 163;
const int maxt = 10;
int A[maxn], B[maxn];
ll frog[maxn][maxm][maxm];
int ReadNum(int *p);
ll calc(const int *const num, const int n);
int main() {
freopen("1.in", "r", stdin);
int x = ReadNum(A), y = ReadNum(B);
ll _sum = 0, _val = 0, _ten = 1;
for (int i = x - 1; ~i; --i) {
_sum += A[i]; _val += A[i] * _ten;
_ten *= 10;
}
qw(calc(B, y) - calc(A, x) + (!(_val % _sum)), '\n', true);
return 0;
}
int ReadNum(int *p) {
auto beg = p;
do *p = IPT::GetChar() - '0'; while ((*p < 0) || (*p > 9));
do *(++p) = IPT::GetChar() - '0'; while ((*p <= 9) && (*p >= 0));
return p - beg;
}
ll calc(const int *const num, const int n) {
int dn = n - 1;
if (n <= 1) { return num[0]; }
ll _ret = 0, _ten = 1;
for (int i = 1; i < n; ++i) _ten *= 10;
for (int p = 1; p < maxm; ++p) {
memset(frog, 0, sizeof frog);
ll ten = _ten; int tm = ten % p;
int upc = num[0] * tm % p, left = p - num[0];
for (int i = 1; i < num[0]; ++i) if (p >= i) {
frog[0][i * tm % p][p - i] = 1;
}
for (int i = 1; i < n; ++i) {
int di = i - 1;
tm = (ten /= 10) % p;
for (int j = 0; j < p; ++j) {
for (int k = 0; k < p; ++k) {
for (int h = 0; h < 10; ++h) if ((h + k) <= p) {
int dh = h * tm % p, dj = j >= dh ? j - dh : j - dh + p;
frog[i][j][k] += frog[di][dj][k + h];
}
}
}
for (int j = 1; j < 10; ++j) if (j <= p) {
++frog[i][j * tm % p][p - j];
}
for (int h = 0; h < num[i]; ++h) if (h <= left) {
int dh = h * tm % p;
++frog[i][(upc + dh) % p][left - h];
}
upc = (upc + num[i] * tm) % p; left -= num[i];
}
_ret += frog[dn][0][0];
if ((upc == 0) && (left == 0)) ++_ret;
}
return _ret;
}
Summary
Read character by character \ (L \) when, \ (L -. 1 \) is not easy to process, as change \ ([1, R] - [1, L] + (L \) is legitimate \ () \ ) .