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;
}

浙公网安备 33010602011771号