Codeforces 2007B Index and Maximum Value 题解 [ 橙 ] [ Ad-hoc ] [ 线段树 ] [ 平衡树 ]

Index and Maximum Value:简单诈骗题。

注意到每次对一个值域区间做加减 \(1\) 的操作,所以所有数之间的相对顺序是不会发生改变的。直接平衡树或者线段树维护即可,时间复杂度 \(O(n\log n)\)

但是因为所有数相对顺序不改变,所以总是存在一个数使得它一直是最大值,直接对最大值进行维护即可。时间复杂度 \(O(n)\)

下面证明一下所有数相对顺序不改变的结论:

  • 若操作的值域为 \([l,r]\),那么显然 \(l\sim r\) 里面的数相对顺序不会改变。
  • 对于 \([-\infty, l-1]\) 的元素,因为改变的值域的最小值为 \(l\),所以改变后最多只会减到 \(l-1\),显然不会改变相对顺序。
  • 对于 \([r+1, \infty]\) 的元素,因为改变的值域的最大值为 \(r\),所以改变后最多只会加到 \(r+1\),显然不会改变相对顺序。
#include <bits/stdc++.h>
#define fi first
#define se second
#define eb(x) emplace_back(x)
#define pb(x) push_back(x)
#define lc(x) (tr[x].ls)
#define rc(x) (tr[x].rs)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ldb;
using pi = pair<int, int>;
const int N = 100005;
int n, m, a, mx;
void solve()
{
    cin >> n >> m;
    mx = 0;
    for(int i = 1; i <= n; i++)
    {
        cin >> a;
        mx = max(mx, a);
    }
    while(m--)
    {
        char op; int l, r;
        cin >> op >> l >> r;
        if(l <= mx && mx <= r)
        {
            if(op == '+') mx++;
            else mx--;
        }
        cout << mx << " ";
    }
    cout << '\n';
}
int main()
{
    //freopen("sample.in", "r", stdin);
    //freopen("sample.out", "w", stdout);
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin >> t;
    while(t--) solve();
    return 0;
}
posted @ 2025-08-13 10:09  KS_Fszha  阅读(10)  评论(0)    收藏  举报