AtCoder ABC322G 数学 + 暴力

题意

传送门 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 b<a b<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<min(10,b) Si<min(10,b)。根据 S 1 ≠ 0 S_1\neq 0 S1=0,可以观察到 k k k 规模为 O ( log ⁡ X ) O(\log X) O(logX)。

先考虑 k k k 较小的情况。当 k = 1 k = 1 k=1,由于 0 < X 0<X 0<X 故无解;当 k = 2 k = 2 k=2,则 ( a − b ) S 1 = X (a-b)S_1=X (a−b)S1=X,枚举 S 1 , S 2 S_1, S_2 S1,S2,则 a a a 的最小值为 max ⁡ ( S 1 , S 2 ) + 1 + X / S 1 \max(S_1, S_2) + 1 + X/S_1 max(S1,S2)+1+X/S1,最后根据 a ≤ N a\leq N a≤N 统计答案即可。

当 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)。

cpp 复制代码
#include <bits/stdc++.h>
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;
}
相关推荐
weixin_307779132 小时前
Redis Windows迁移方案与测试
c++·windows·redis·算法·系统架构
仪器科学与传感技术博士4 小时前
python:讲懂决策树,为理解随机森林算法做准备,以示例带学习,通俗易懂,容易理解和掌握
python·算法·决策树
小指纹4 小时前
cf--思维训练
c++·算法·macos·ios·objective-c·cocoa
小指纹4 小时前
河南萌新联赛2025第(四)场【补题】
数据结构·c++·算法·macos·objective-c·cocoa·图论
菜鸟555554 小时前
河南萌新联赛2025第四场-河南大学
c++·算法·思维·河南萌新联赛
F_D_Z5 小时前
【感知机】感知机(perceptron)模型与几何解释
学习·算法·支持向量机
竹子_235 小时前
《零基础入门AI:传统机器学习进阶(从拟合概念到K-Means算法)》
人工智能·算法·机器学习
设计师小聂!6 小时前
力扣热题100------136.只出现一次的数字
数据结构·算法·leetcode
崎岖Qiu6 小时前
leetcode643:子数组最大平均数 I(滑动窗口入门之定长滑动窗口)
java·算法·leetcode·力扣·双指针·滑动窗口
多思考少编码7 小时前
[GESP202309 四级] 2023年9月GESP C++四级上机题题解,附带讲解视频!
开发语言·c++·算法