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;
}
相关推荐
智者知已应修善业3 小时前
【51单片机8位数码管同时倒计时从9999】2024-1-25
c++·经验分享·笔记·算法·51单片机
洛水水3 小时前
【力扣100题】86.柱状图中最大的矩形
算法·leetcode·职场和发展
渡之3 小时前
GRiM-Net 深度解析 | 无人机 GNSS 拒止场景下两阶段跨视角视觉定位框架
深度学习·算法·动态规划·无人机
测试仪器廖生135902563853 小时前
罗德与施瓦茨 FSP13频谱分析仪FSP30
网络·人工智能·算法
happymaker06263 小时前
LeetCodeHot100——560.和为K的子数组
算法
dtq04243 小时前
C语言刷题数组5,6(求平均值,求最大值)
c语言·数据结构·算法
郭梧悠4 小时前
Hash算法入门Hash冲突解决方案
算法·哈希算法
洛水水4 小时前
【力扣100题】81.寻找两个正序数组的中位数
数据结构·算法·leetcode
happymaker06265 小时前
LeetCodeHot100——155.最小栈
算法
洛水水5 小时前
【力扣100题】85.每日温度
算法·leetcode·职场和发展