传送门 AtCoder ABC322G Two Kinds of Base
根据 1 ≤ X 1\leq X 1≤X,以及 f ( S , a ) f(S,a) f(S,a) 关于 a a a 的递增性,可以得到 b < a bb<a。此时 S i < min ( 10 , a , b ) S_i<\min(10,a,b) Si<min(10,a,b) 简化为 S i < m i n ( 10 , b ) S_i
先考虑 k k k 较小的情况。当 k = 1 k = 1 k=1,由于 0 < X 0
当 k ≥ 3 k\geq 3 k≥3,则满足 a 2 − b 2 ≤ X a^2-b^2\leq X a2−b2≤X,令 d = a − b d = a - b d=a−b,则有 2 b + d ≤ X / d 2b+d\leq X/d 2b+d≤X/d,可以推出满足条件的 ( a , b ) (a,b) (a,b) 数目为 O ( X log X ) O(X\log X) O(XlogX)。那么枚举满足 d ∣ X d|X d∣X 的 d d d,再根据上界枚举 b b b 即可得到所有的 ( a , b ) (a,b) (a,b) 二元组。问题转化为 a , b a,b a,b 固定后满足条件的 S S S 数量,由于 S i S_i Si 上界为 b − 1 b-1 b−1,同时根据等比数列求和公式,可以得到 a k − b k > ( b − 1 ) ∑ i = 0 k − 1 ( a i − b i ) a^k-b^k>(b-1)\sum_{i = 0}^{k-1}(a^i-b^i) ak−bk>(b−1)∑i=0k−1(ai−bi),可以推出满足条件的 S k , S k − 1 , ⋯ , S 2 S_k,S_{k-1},\cdots,S_2 Sk,Sk−1,⋯,S2 至多有一种可能,按照 k k k 从大到小依次减去 a k − b k a^k-b^k ak−bk 的贡献,判断 f ( S , a ) − f ( S , b ) = X f(S,a)-f(S,b)=X f(S,a)−f(S,b)=X 是否成立即可,若成立,对答案贡献为 min ( 10 , b ) \min(10,b) min(10,b)。总时间复杂度 O ( X log 2 X ) O(X\log^2 X) O(Xlog2X)。
#include
using namespace std;
constexpr int MOD = 998244353;
using ll = long long;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, x;
cin >> n >> x;
ll res = 0;
for (int s1 = 1; s1 < 10; ++s1) {
if (x % s1 > 0) {
continue;
}
for (int s2 = 0; s2 < 10; ++s2) {
int d = x / s1;
int mn = max(s1, s2) + 1 + d;
(res += max(0, n - mn + 1)) %= MOD;
}
}
for (int d = 1; d <= x; ++d) {
if (x % d > 0) {
continue;
}
for (int b = 1, a = b + d; a <= n && (ll)a * a - (ll)b * b <= x; ++b, ++a) {
vector<int> as, bs;
ll aa = 1, bb = 1;
while (aa - bb <= x) {
as.push_back(aa);
bs.push_back(bb);
aa *= a, bb *= b;
}
int rem = x;
for (int i = (int)bs.size() - 1; i > 0; --i) {
int t = rem / (as[i] - bs[i]);
if (t >= min(10, b)) {
break;
}
rem -= t * (as[i] - bs[i]);
}
if (rem == 0) {
res += min(10, b);
}
}
}
res %= MOD;
cout << res << '\n';
return 0;
}