1 条题解

  • 0
    @ 2025-11-13 10:27:23

    题目理解

    我们有 NN 个选手排成一列,旗手在最前面。每个选手 ii 有一个参数 DiD_i 控制其移动规则:

    • 如果与前面的人距离 Di\le D_i,则不动
    • 如果距离 Di+1\ge D_i+1,则立即前进到距前者 11 单位的位置

    我们需要回答 QQ 个查询:在时刻 TjT_j,位置在 [Lj,Rj][L_j, R_j] 区间内的选手数量。

    问题分析

    1. 移动规律分析

    通过观察可以发现,选手的移动具有周期性分组性

    • 选手们会形成若干组,组内选手保持相对位置不变
    • 每组选手的移动模式相同,具有周期性
    • 每个组在移动时作为一个整体前进

    2. 关键观察

    选手 ii 的移动模式取决于前面选手的移动模式。具体来说:

    • 选手们会形成连续的块(block),块内选手共享相同的移动周期
    • 每个块有固定的周期 pp 和每周期前进距离 ww

    算法思路

    1. 预处理块信息

    代码的核心是预处理出选手的分块信息:

    vector<long long> p(n + 1, inf), w(n + 1, 0);
    p[0] = 1;  // 旗手的周期
    w[0] = 1;  // 旗手每周期前进距离
    
    for (int i = 1; i <= n; i++) {
        p[i] = (d[i] + w[i - 1] - 1) / w[i - 1] * p[i - 1];
        w[i] = p[i] / p[i - 1] * w[i - 1];
        
        if (p[i] > inf) break;
    }
    

    这里:

    • p[i]:选手 ii 所在块的移动周期
    • w[i]:选手 ii 所在块每周期前进的距离

    2. 分块处理

    将具有相同周期的连续选手划分为一个块:

    vector<pair<int, int>> block;
    for (int l = 0, r = 0; l <= n; l = r + 1) {
        r = l;
        while (r <= n && p[l] == p[r]) r++;
        r--;
        block.push_back({l, r});
    }
    

    3. 查询处理

    对于每个查询,计算每个块在时刻 TT 时的位置范围:

    for (auto [L, R] : block) {
        long long per = p[L], walk = w[L];
        int go = t / per * walk;  // 总前进距离
        int cl = l - go, cr = r - go;  // 相对位置
        
        // 计算在相对位置[cl, cr]内的选手数量
        ans += max(0, min(cr, -L) - max(cl, -R) + 1);
    }
    

    关键算法细节

    1. 周期计算原理

    对于选手 ii

    • 如果 Di<w[i1]D_i < w[i-1],则与前面选手保持相同周期
    • 如果 Diw[i1]D_i \ge w[i-1],则形成新的周期:
      p[i] = ceil(D_i / w[i-1]) * p[i-1]
      w[i] = p[i] / p[i-1] * w[i-1]
      

    2. 位置计算

    在时刻 TT,一个周期为 pp、每周期前进 ww 的块的总前进距离为:

    前进距离 = (T / p) * w
    

    选手 ii 的绝对位置为:

    位置 = 前进距离 - i
    

    3. 区间计数

    对于块 [L,R][L, R],在相对坐标系中:

    • 选手 ii 的相对位置是 i-i
    • 查询区间 [l,r][l, r] 映射到相对坐标系为 [lgo,rgo][l-go, r-go]
    • 计算相对位置在 [cl,cr][cl, cr] 内的选手数量

    复杂度分析

    • 预处理O(N)O(N)
    • 每个查询O(块数)O(\text{块数}),块数最多为 O(logN)O(\log N)
    • 总复杂度O(N+QlogN)O(N + Q\log N)

    对于 N,Q5×105N, Q \le 5\times 10^5,这是可接受的。

    算法优化

    1. 提前终止

    当周期超过数据范围时提前终止:

    if (p[i] > inf) break;
    

    2. 整数运算

    所有计算使用整数运算,避免浮点数误差。

    算法标签

    • 数学:周期性分析、整数运算
    • 分块思想:将选手按移动模式分组
    • 预处理:预先计算所有块的周期信息
    • 区间计数:高效回答区间查询

    总结

    这道题通过深入分析选手移动的周期性规律,将问题转化为分块处理:

    1. 规律发现:识别出选手移动的周期性和分组性
    2. 数学建模:用周期 pp 和前进距离 ww 描述每个块的移动
    3. 高效查询:利用分块信息快速回答位置查询
    4. 边界处理:正确处理各种边界情况

    该解法充分利用了问题的特殊性质,通过数学分析和分块技术实现了高效查询,是数学思维与算法设计的完美结合。

    • 1

    信息

    ID
    5321
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者