1. 复杂度分析

    本题要求在长度为 N 的序列中, 求出所有长度为 M 的连续子区间的 mex 值的最小值.

    根据题意, 数据规模达到了 N, M <= 2000000.常规的"滑动窗口结合平衡树或权值树状数组"解法, 其时间复杂度为 . 在极大的常数开销与 2 秒的严格时限下, 这种做法存在较高的超时 (TLE) 风险.

    因此, 寻求一种纯线性 的解法是更为稳妥的选择.

  2. 核心算法:

    最大间隔判定我们可以从"最终结果"出发进行逆向推导.

    假设最终求得的最小 mex 值为 x, 这意味着具备以下两个推论:必定存在至少一个长度为 M 的区间, 其内部不包含数字 x.对于所有严格小于 x 的非负整数 (即 0 到 x-1), 它们必须在每一个长度为 M 的区间内都出现过.

    为了判断某个数字 y 是否在所有长度为 M 的区间中均存在, 我们可以考察该数字在原数组中相邻两次出现位置的最大间隔 (Maximum Gap).

    若数字 y 的最大间隔 <= M, 则任何长度为 M 的窗口在滑动时, 都必然会覆盖到至少一个 y.若数字 y 的最大间隔 > M, 则说明原数组中存在一段长度大于 M 的连续区间不包含 y.

    我们完全可以将滑动窗口置于该区间内, 从而使得窗口内缺失数字 y.基于此结论, 我们只需从 0 开始, 依次递增检查每个自然数的最大间隔. 遇到的首个满足"最大间隔 > M"的自然数, 即为我们要寻找的最小 mex 值.

  3. 算法实现步骤设定边界:

    为便于计算首末两端的间隔, 引入虚拟的起始位置 -1 与结束位置 N.

    控制值域: 窗口长度最大为 N, 因此 mex 的结果不可能超过 N+1.

    我们仅需开辟大小为 N+2 的数组记录位置信息, 超出此范围的数值对答案无影响.

    遍历更新: 单次遍历输入数组, 使用 last_pos 记录每个有效数字上一次出现的位置, 并同步动态更新 max_gap 数组.

    末端处理: 遍历完成后, 补充计算各数字最后一次出现位置至数组末端边界 N 的间隔.输出结果: 从 0 开始顺序遍历 max_gap 数组, 输出首个满足 max_gap[i] > M 的索引 i.

4.参考代码C++

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl "\n"
void solve()
{
    int n, m;
    cin >> n >> m;
    // 记录数字上一次出现的位置, 初始边界统一设定为 -1
    vector<int> last_pos(n + 2, -1);
    // 记录数字相邻出现的最大间隔
    vector<int> max_gap(n + 2, 0);
    for(int i = 0; i < n; i++)
    {
        int val;
        cin >> val;
        // 仅处理可能成为最终 mex 值的有效数据 (<= n+1)
        if(val <= n + 1)
        {
            max_gap[val] = max(max_gap[val], i - last_pos[val]);
            last_pos[val] = i;
        }
    }
    // 从 0 开始逐一验证自然数
    for(int i = 0; i <= n + 1; i++)
    {
        // 补充计算至数组末尾边界 n 的距离
        max_gap[i] = max(max_gap[i], n - last_pos[i]);
        // 寻找首个最大间隔超过窗口长度 m 的数字
        if(max_gap[i] > m)
        {
            cout << i << endl;
            return;
        }
    }
}
signed main(){
    // 优化标准输入输出流的性能
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    solve();
    return 0;
}
  1. 复杂度总结时间复杂度: . 算法仅对序列进行了一次常数级别的线性遍历, 避免了对数级别数据结构的维护开销, 运行效率极高.空间复杂度: . 仅借助两个大小为 N+2 的一维数组记录位置与间隔信息, 完全符合内存限制要求.