很有意思的一个题,想要高效的完成这个题目我们可以关注每一次操作的本质,对于比较特殊的

例如 1 2 3 4 5 这种没有0的mex为0,不管多少次操作都是无效的 0 0 0 0 0 这种不需要操作就可以

分析完了特殊的我们可以来看比较一般的情况,例如 0 2026 由于数组有0才能有有效的mex本质上所有的操作最后都会来到这一步,即每次让下一个值减1

0 4 -> 0 3 -> 0 2 -> 01 -> 0 0(4次)

0 2026 -> 0 2025 - > ... -> 0 1 -> 0 0(2026次操作)

我们可以特殊化一点插入一个数字观察会有什么效应,来把这个问题泛化,

0 1 2026 -> 0 0 2024(2025次操作)连续的数字可以减少操作次数

0 1 4 2026 -> 0 0 2 2024 -> 0 0 1 2023 -> 0 0 0 2021(2024次)好像非连续的也可以减少操作次数

现在就比较明显了,中间每出现一个非零的数字,无论大小都会使得总操作次数减少1次,这是因为虽然减去的总数不变但是在有中间数字的情况下面,每一次在这个数归零的时候都会使得最后的操作次数-1

因为每一个存在的不同正整数,都会让mex 在某一轮中比原先大 1,从而让 nums[n-1]多减少 1。

那么答案就是 nums[n-1] - 非零数字的个数 + 1(对于重复的一次操作就可以使其合法)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    int n;
    cin >> n;
    vector<ll> nums(n);
    for(int i = 0; i < n; i++) cin >> nums[i];
    sort(nums.begin(),nums.end());
    if(nums[n-1]==nums[0])
    {
        cout << "0" << endl;
        return 0;
    }
    if(nums[0]>0)
    {
        cout << "-1" << endl;
        return 0;
    }
    set<ll> s;
    for(int i = 0; i < n; i++)
    {
        if(nums[i]!=0)
        {
            s.insert(nums[i]);
        }
    }
    ll ans = nums[n-1] - s.size()+1 ;
    cout << ans << endl;
}