Post

CF1862G The Great Equalizer

CF1862G The Great Equalizer

本题是一道关于序列操作的算法题,需要对给定的初始序列进行排序去重,并通过对数列中不同位置元素加上不同的常数来更新序列。具体实现可以使用 set 和 multiset 分别维护当前数列和相邻两数差距,进而求得最大的相邻两数差距作为总的操作次数。每次操作后输出数列中最大值加上操作次数的结果。

题目大意

有一台机器,他会对一个序列执行以下操作:

  1. 对序列排序并去重
  2. 如果序列中只剩下一个数,将它输出,结束操作
  3. 对数列的第 $n,n-1,…,1$ 项加上 $1,2,…,n$,返回到第一步

给定一个初始序列,每次更改一个序列中元素的值(更改会一直保留)并输出当前序列放入机器中输出的结果。

思路

首先明确一点,数列中的最大项会在操作过程中一直是最大值,并且每次操作后将它加上 $1$,因此,最后输出的结果一定是数列中最大值加上操作次数,问题转变为求操作次数。

每次操作所产生的效果是相邻两数的差距缩小 $1$,当所有相邻两数差距都为 $0$ 时,操作结束。因此,总的操作次数应为相邻两数差距的最大值。

用 set 和 multiset 分别维护当前数列和相邻两数差距即可。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
int n, a[maxN + 5], aa[maxN + 5], q, idx, x;
set<int> ss;
map<int, int> num;
multiset<int> gap;
void mset_del(int x) {
    auto it = gap.lower_bound(x);
    if (it != gap.end())
        gap.erase(it);
}
void solve() {
    cin >> n;
    ss.clear(), num.clear(), gap.clear();
    //  gap.insert(0);
    rep(i, 1, n) {
        cin >> a[i];
        aa[i] = a[i];
        ss.insert(a[i]);
        num[a[i]]++;
    }
    sort(aa + 1, aa + 1 + n);
    rep(i, 2, n) gap.insert(aa[i] - aa[i - 1]);
    cin >> q;
    while (q--) {
        cin >> idx >> x;
        if (ss.size() == 1) {
            if (n == 1 || x == a[idx]) {
                num[a[idx]]--, num[x]++;
                ss.erase(a[idx]), ss.insert(x);
                cout << x << " ";

            } else {
                num[a[idx]]--, num[x]++;
                ss.insert(x);
                gap.insert(abs(x - a[idx]));
                cout << (*prev(ss.end()) + *prev(gap.end())) << " ";
            }
            a[idx] = x;
            continue;
        }
        if (--num[a[idx]] == 0) {
            auto it = ss.lower_bound(a[idx]);
            if (it == ss.begin()) {
                mset_del(*next(it) - *it);
            } else if (next(it) == ss.end()) {
                mset_del(*it - *prev(it));
            } else {
                mset_del(*next(it) - *it);
                mset_del(*it - *prev(it));
                gap.insert(*next(it) - *prev(it));
            }
            ss.erase(a[idx]);
        }
        if (++num[x] == 1) {
            ss.insert(x);
            auto it = ss.lower_bound(x);
            if (it == ss.begin()) {
                gap.insert(*next(it) - *it);
            } else if (next(it) == ss.end()) {
                gap.insert(*it - *prev(it));
            } else {
                mset_del(*next(it) - *prev(it));
                gap.insert(*next(it) - *it);
                gap.insert(*it - *prev(it));
            }
        }
        a[idx] = x;
        if (ss.size() == 1)
            cout << *ss.begin() << " ";
        else
            cout << (*prev(ss.end()) + *prev(gap.end())) << " ";
    }
    cout << endl;
}
This post is licensed under CC BY 4.0 by the author.