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 @   HappyBobb  阅读(7)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示