模板(重载运算符部分需要结合具体题目)
const int N = $$;
template <class info> struct SegmentTree
{
int n;
vector<info> val;
SegmentTree(int n_)
{
n = n_;
val.resize(n << 2);
}
SegmentTree(int n_, vector<info> &a)
{
n = n_;
val.resize(n << 2);
function<void(int, int, int)> build = [&](int now, int l, int r) {
if (l == r)
{
val[now] = a[l];
return;
}
int mid = l + (r - l) / 2;
build(now << 1, l, mid);
build(now << 1 | 1, mid + 1, r);
pushup(now);
};
build(1, 1, n);
}
void pushup(int now)
{
val[now] = val[now << 1] + val[now << 1 | 1];
}
void update(int now, int l, int r, int pos, const info &v)
{
if (l == r)
{
val[now] = v;
return;
}
int mid = l + (r - l) / 2;
if (pos <= mid)
{
update(now << 1, l, mid, pos, v);
}
else
{
update(now << 1 | 1, mid + 1, r, pos, v);
}
pushup(now);
}
info query(int now, int l, int r, int L, int R)
{
if (l > R || r < L)
{
return info();
}
if (l >= L && r <= R)
{
return val[now];
}
int mid = l + (r - l) / 2;
return query(now << 1, l, mid, L, R) + query(now << 1 | 1, mid + 1, r, L, R);
}
template <class T> int findfirst(int now, int l, int r, T func)
{
if (!func(val[now]))
{
return -1;
}
if (l == r)
{
return l;
}
int mid = l + (r - l) / 2;
int ret = findfirst(now << 1, l, mid, func);
if (ret == -1)
{
ret = findfirst(now << 1 | 1, mid + 1, r, func);
}
return ret;
}
template <class T> int findlast(int now, int l, int r, T func)
{
if (!func(val[now]))
{
return -1;
}
if (l == r)
{
return l;
}
int mid = l + (r - l) / 2;
int ret = findlast(now << 1 | 1, mid + 1, r, func);
if (ret == -1)
{
ret = findlast(now << 1, l, mid, func);
}
return ret;
}
};
struct info
{
int x = 0;
};
SegmentTree<info> seg(N);
info operator+(const info &a, const info &b)
{
info ret;
ret.x = max(a.x, b.x);
return ret;
}
code
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
// #define int ll
const int N = 2E6 + 5;
template <class info> struct SegmentTree
{
int n;
vector<info> val;
SegmentTree(int n_)
{
n = n_;
val.resize(n << 2);
}
SegmentTree(int n_, vector<info> &a)
{
n = n_;
val.resize(n << 2);
function<void(int, int, int)> build = [&](int now, int l, int r) {
if (l == r)
{
val[now] = a[l];
return;
}
int mid = l + (r - l) / 2;
build(now << 1, l, mid);
build(now << 1 | 1, mid + 1, r);
pushup(now);
};
build(1, 1, n);
}
void pushup(int now)
{
val[now] = val[now << 1] + val[now << 1 | 1];
}
void update(int now, int l, int r, int pos, const info &v)
{
if (l == r)
{
val[now] = v;
return;
}
int mid = l + (r - l) / 2;
if (pos <= mid)
{
update(now << 1, l, mid, pos, v);
}
else
{
update(now << 1 | 1, mid + 1, r, pos, v);
}
pushup(now);
}
info query(int now, int l, int r, int L, int R)
{
if (l > R || r < L)
{
return info();
}
if (l >= L && r <= R)
{
return val[now];
}
int mid = l + (r - l) / 2;
return query(now << 1, l, mid, L, R) + query(now << 1 | 1, mid + 1, r, L, R);
}
template <class T> int findfirst(int now, int l, int r, T func)
{
if (!func(val[now]))
{
return -1;
}
if (l == r)
{
return l;
}
int mid = l + (r - l) / 2;
int ret = findfirst(now << 1, l, mid, func);
if (ret == -1)
{
ret = findfirst(now << 1 | 1, mid + 1, r, func);
}
return ret;
}
template <class T> int findlast(int now, int l, int r, T func)
{
if (!func(val[now]))
{
return -1;
}
if (l == r)
{
return l;
}
int mid = l + (r - l) / 2;
int ret = findlast(now << 1 | 1, mid + 1, r, func);
if (ret == -1)
{
ret = findlast(now << 1, l, mid, func);
}
return ret;
}
};
struct info
{
int x = 0;
};
SegmentTree<info> seg(N);
info operator+(const info &a, const info &b)
{
info ret;
ret.x = max(a.x, b.x);
return ret;
}
void solve()
{
int n;
cin >> n;
set<int> s{0, 2 * N};
seg.update(1, 1, N, 1, {2 * N - 1});
auto ins = [&](int x) {
auto it = s.insert(x).first;
int l = *prev(it);
int r = *next(it);
seg.update(1, 1, N, l + 1, {x - l - 1});
seg.update(1, 1, N, x + 1, {r - x - 1});
};
auto del = [&](int x) {
auto it = s.find(x);
int l = *prev(it);
int r = *next(it);
seg.update(1, 1, N, l + 1, {r - l - 1});
seg.update(1, 1, N, x + 1, {});
s.erase(x);
};
for (int i = 1; i <= n; i++)
{
int x;
cin >> x;
ins(x);
}
int q;
cin >> q;
for (int i = 1; i <= q; i++)
{
char op;
int x;
cin >> op >> x;
if (op == '+')
{
ins(x);
}
else if (op == '-')
{
del(x);
}
else
{
int ans = seg.findfirst(1, 1, N, [&](info &a) { return a.x >= x; });
cout << ans << " ";
}
}
for (auto x : s)
{
seg.update(1, 1, N, x + 1, {});
}
cout << "\n";
}
signed main()
{
ios::sync_with_stdio(false), cin.tie(nullptr);
int t = 1;
cin >> t;
while (t--)
{
solve();
}
}