1 条题解

  • 0
    @ 2026-5-17 14:33:40

    题目 B. ICPC Square 详细题解

    问题重述

    NN 层楼(编号 11NN),电梯规则:从 xx 层可以到 yy 层当且仅当

    • yyxx 的倍数,且
    • yxDy - x \le D

    初始在 SS 层,可以乘坐零次或多次电梯,问能到达的最高楼层(不超过 NN)。

    关键观察

    1. 可达楼层必为 SS 的倍数
      因为从 SS 出发,每次跳到的都是当前楼层的倍数,所以所有可达楼层都是 SS 的倍数。

    2. 归一化
      将问题除以 SS:令

      $$N' = \left\lfloor \frac{N}{S} \right\rfloor,\quad D' = \left\lfloor \frac{D}{S} \right\rfloor $$

      起始楼层变为 11,目标是在 [1,N][1, N'] 内从 11 出发,每次可以跳到当前数 xx 的倍数 yyyxDy - x \le D'
      最终答案乘以 SS 即可。

    可达上界分析

    设当前在 xx,下一次跳到 y=kxy = kxk2k \ge 2 整数)。则增量

    yx=(k1)xxy - x = (k-1)x \ge x

    因此 xyxDx \le y - x \le D',即 xDx \le D'

    结论:任何非自身的倍数跳跃,其起点必须 D\le D'

    若想跳到较大的数 YY,它必须有一个真因子 XXX<YX < Y)满足 XDX \le D'YXDY - X \le D'
    由于 X1X \ge 1,且 YY 的最小真因子最大为 Y/2Y/2(当 YY 为偶数时),所以

    YXYY2=Y2Y - X \ge Y - \frac{Y}{2} = \frac{Y}{2}

    因此 Y2D\frac{Y}{2} \le D',即 Y2DY \le 2D'

    另外显然 YNY \le N'。故能到达的楼层 不可能超过

    Ymax=min(2D, N)Y_{\max} = \min(2D',\ N')

    能否到达 YmaxY_{\max} 的判断

    Y=YmaxY = Y_{\max}。若 Y=0Y = 0(即 D=0D' = 0N=0N' = 0?实际上 N1N' \ge 1 因为 SNS \le N),则起始楼层 11 就是答案。下文假设 Y1Y \ge 1

    情况 1:YY 是偶数

    X=Y/2X = Y/2,则

    • XX 是整数且 XDX \le D'(因为 Y2DY \le 2D'),
    • 11 可以直接跳到 XXXX11 的倍数且 X1DX-1 \le D' 成立(因 XDD+1X \le D' \le D'+1),
    • XX 可以跳到 YYYYXX 的倍数且 YX=Y/2DY-X = Y/2 \le D'
      因此 YY 可达。

    情况 2:YY 是奇数

    需要寻找一个真因子 XX 满足:

    • XDX \le D'
    • YYXX 的倍数,
    • YXDY - X \le D'

    由于 YY 是奇数,其最小真因子 XminX_{\min} 可能大于 Y/2Y/2?实际上奇数的最小真因子最大为 Y/3Y/3(例如 99 的因子 33)。但更通用的方法是枚举 YY 的所有因子 XXXYX \ne Y),检查是否 XDX \le D'YXDY - X \le D'
    因为 Y2DY \le 2D',所以 YXDY - X \le D' 等价于 XYDX \ge Y - D'。因此需要存在一个真因子 XX 满足

    YDXDY - D' \le X \le D'

    XYX \mid Y

    枚举 YY 的所有因子可在 O(Y)O(\sqrt{Y}) 时间内完成。若找到这样的 XX,则 YY 可达(从 11 跳到 XX,再跳到 YY)。若找不到,则 YY 不可达。

    不可达时的次优解

    YY 不可达,则 Y1Y-1 一定是偶数(因为 YY 是奇数),且 Y12DY-1 \le 2D',故根据情况 1,Y1Y-1 可达。因此答案为 Y1Y-1

    算法步骤

    1. 读取 N,D,SN, D, S
    2. 计算 N=N/SN' = \lfloor N/S \rfloorD=D/SD' = \lfloor D/S \rfloor
    3. D=0D' = 0,则只能停留在 11,答案为 SS。否则:
      • Y=min(2D, N)Y = \min(2D',\ N')
      • 如果 YY 是偶数,则 ans=Yans = Y
      • 否则(YY 奇数),枚举 YY 的所有因子 XX1XY1 \le X \le \sqrt{Y}),检查是否存在真因子 XX 满足 YDXDY-D' \le X \le D'XYX \mid Y
        • 若存在,则 ans=Yans = Y
        • 否则 ans=Y1ans = Y-1
    4. 输出 ans×Sans \times S

    复杂度分析

    • 归一化 O(1)O(1)
    • 枚举因子 O(Y)O(N)O(\sqrt{Y}) \le O(\sqrt{N}),因为 YNN/SNY \le N' \le N/S \le N
    • 总时间复杂度 O(N)O(\sqrt{N}),可轻松通过 N1012N \le 10^{12}

    边界情况处理

    • S>DS > D 时,D=0D' = 0,直接输出 SS(只能停留在起点)。
    • S=NS = N 时,N=1N' = 1Y=min(2D,1)=1Y = \min(2D',1)=1,此时 11 可达(起点本身),答案为 SS,正确。
    • Y=1Y=1 时(奇数),因子只有 11,检查 11 是否在 [YD,D][Y-D', D'] 内,即 [1D,D][1-D', D']。由于 D1D' \ge 111 满足,故 YY 可达,答案正确。

    参考代码(C++)

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    int main() {
        ll N, D, S;
        cin >> N >> D >> S;
        ll Np = N / S;
        ll Dp = D / S;
        if (Dp == 0) {
            cout << S << endl;
            return 0;
        }
        ll Y = min(2 * Dp, Np);
        if (Y % 2 == 0) {
            cout << Y * S << endl;
            return 0;
        }
        // Y is odd, check if reachable
        bool ok = false;
        for (ll x = 1; x * x <= Y; ++x) {
            if (Y % x == 0) {
                ll f1 = x, f2 = Y / x;
                if (f1 != Y && f1 >= Y - Dp && f1 <= Dp) ok = true;
                if (f2 != Y && f2 >= Y - Dp && f2 <= Dp) ok = true;
            }
        }
        if (ok) cout << Y * S << endl;
        else cout << (Y - 1) * S << endl;
        return 0;
    }
    
    • 1

    信息

    ID
    7153
    时间
    1000ms
    内存
    256MiB
    难度
    4
    标签
    递交数
    0
    已通过
    0
    上传者