C - Snake Numbers 解説 by en_translator
In the problem statement, Snake numbers are only defined for integers at least \(10\), but in this editorial, we define that every positive integer less than \(10\) is also a Snake number. (Since \(L \geq 10\), we can define Snake numbers for integers less than \(10\) anyhow.)
Define \(f(R)\) as the number of integers less than or equal to \(R\). The sought count can be represented as \(f(R)-f(L-1)\), so it is sufficient to find \(f(R)\) for an arbitrarily given positive integer \(R\). We will explain how.
First of all, \(R\) can be at most \(10^{18}\), so we cannot check for each integer less than or equal to \(R\) whether it is a Snake number or not. Instead, we have to observe the decimal representation of \(R\) to count the number of Snake numbers no greater than \(R\) efficiently.
Suppose that \(R\) has \(n\) digits in decimal, and its \(i\)-th \((1\leq i\leq n)\) significant digit is \(d_i\). Then, every positive integer \(x\) less than or equal to \(R\) satisfies exactly one of the following conditions. Conversely, every positive integer \(x\) satisfying any of the following is less than or equal to \(R\).
- \(x=R\).
- \(x\) has \(n\) digits. Its first \(k\ (1\leq k\leq n-1)\) digits coincide with those of \(R\), and the \((k+1)\)-th one is less than \(d_{k+1}\).
- \(x\) has \(n\) digits. Its first digit is less than \(d_1\).
- \(x\) has \(k\) digits \((1\leq k\leq n-1)\).
For each of 1 to 4 above, consider counting the number of positive integers \(x\) that are Snake numbers. Then we have the following:
- If \(R\) is a Snake number (that is, if \(d_1 > d_i\) for all \(i\ (2\leq i\leq n)\)), there is one. Otherwise, there are none.
- If \(d_1 \leq d_i\) for some \(i\ (2\leq i\leq k)\), then there are none. Otherwise, the \((k+1)\)-th digit should be less than \(d_1\) and \(d_{k+1}\), and the \((k+2)\)-th and succeeding digits should be less than \(d_1\), so there are \(\min\{d_1, d_{k+1}\}\times d_1^{n-(k+1)}\) of them.
- The first digit should be between \(1\) (inclusive) and \(d_1\) (exclusive), and the other digits should be less than it, so there are \(\displaystyle \sum_{i=1}^{d_1-1} i^{n-1}\) of them.
- The first digit should be between \(1\) and \(9\) (inclusive), and the other digits should be less than it, so there are \(\displaystyle \sum_{i=1}^{9} i^{k-1}\).
The answer can be found as their sum. Note that you need to sum up 2 and 4 for all \(k=1,2,\dots,n-1\).
In the following sample code, we compute 1 and 2 at once, and 3 and 4 at once.
Sample code (C++):
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
ll int_pow(ll a, ll t) {
ll res = 1;
for (int i = 0; i < t; i++) res *= a;
return res;
}
ll count(ll r) {
vector<int> digit;
while (r) {
digit.push_back(r % 10);
r /= 10;
}
reverse(digit.begin(), digit.end());
int n = digit.size();
ll res = 0;
for (int i = 1; i <= n; i++) {
if (i == n) {
res++;
break;
}
res += int_pow(digit[0], n - 1 - i) * min(digit[0], digit[i]);
if (digit[i] >= digit[0]) break;
}
for (int i = 0; i < n; i++) {
int mx = (i ? 9 : digit[0] - 1);
for (int j = 1; j <= mx; j++) {
res += int_pow(j, n - 1 - i);
}
}
return res;
}
int main() {
ll l, r;
cin >> l >> r;
cout << count(r) - count(l - 1) << endl;
}
投稿日時:
最終更新: