CF1862G The Great Equalizer 题解

很简单的结论。

发现有一步十分重要,就是去重。我们考虑对于有序的无重序列中两个数 aia_iaja_j,假设 i<ji<jaia_i 加上的是 nin-iaja_j 加上的是 njn-j。因为 ajaijia_j-a_i \geq j - i,所以 ai+niaj+nja_i + n - i \leq a_j + n - j。所以无论怎么加,最终那个数都是从最大的数得到的。

一次操作,相邻两个数差减 11。所以答案等于最大数 ++ 排序后相邻两个数差最大值。

容易用 multiset 维护。

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

const int N = 2e5 + 5;

int t, n, q;

int a[N];
map<int, int> cnt;

int main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    cin >> t;
    while (t--)
    {
        set<int> s1;
        multiset<int> s2;
        cnt.clear();
        cin >> n;
        for (int i = 1; i <= n; i++) cin >> a[i], s1.insert(a[i]), cnt[a[i]]++;
        for (auto it = ++s1.begin(); it != s1.end(); ++it)
        {
            auto g = it;
            --g;
            s2.insert(*it - *g);
        }
        cin >> q;
        while (q--)
        {
            int i, x;
            cin >> i >> x;
            auto it = s1.lower_bound(a[i]);
            if (cnt[a[i]] == 1 and it != --s1.end())
            {
                auto g = it;
                ++g;
                s2.erase(s2.find(*g - *it));
            }
            if (cnt[a[i]] == 1 and it != s1.begin())
            {
                auto g = it;
                --g;
                s2.erase(s2.find(*it - *g));
            }
            if (cnt[a[i]] == 1 and it != --s1.end() and it != s1.begin())
            {
                auto g1 = it, g2 = it;
                g1--, g2++;
                s2.insert(*g2 - *g1);
            }
            cnt[a[i]]--;
            cnt[x]++;
            if (cnt[a[i]] == 0) s1.erase(it);
            a[i] = x;
            s1.insert(x);
            it = s1.lower_bound(x);
            if (cnt[x] == 1 and it != --s1.end())
            {
                auto g = it;
                ++g;
                s2.insert(*g - *it);
            }
            if (cnt[a[i]] == 1 and it != s1.begin())
            {
                auto g = it;
                --g;
                s2.insert(*it - *g);
            }
            if (cnt[a[i]] == 1 and it != --s1.end() and it != s1.begin())
            {
                auto g1 = it, g2 = it;
                g1--, g2++;
                s2.erase(s2.find(*g2 - *g1));
            }
            if (n == 1) cout << x << " ";
            else if (s1.size() == 1) cout << *s1.begin() << " ";
            else cout << *s1.rbegin() + *s2.rbegin() << " ";
        }
        cout << "\n";
    }
    return 0;   
}
posted @ 2023-08-26 11:51  HappyBobb  阅读(17)  评论(0)    收藏  举报  来源