/* Problem URL: https://codeforces.com/gym/105789/problem/F */ #include #include #include using namespace std; using namespace __gnu_pbds; template > using ordered_set = tree; #define V vector #define rmin(a, b) a = min(a, b) #define rmax(a, b) a = max(a, b) #define rep(i, lim) for (int i = 0; i < (lim); i++) #define nrep(i, s, lim) for (int i = s; i < (lim); i++) #define repv(i, v) for (auto &i : (v)) #define fillv(v) for (auto &itr_ : (v)) { cin >> itr_; } #define sortv(v) sort(v.begin(), v.end()) #define all(v) (v).begin(), (v).end() using vi = vector; using vvi = vector; using vvvi = vector; using vvvvi = vector; using ll = long long; using vl = vector; using vvl = vector; using vvvl = vector; using vvvvl = vector; template auto operator<<(ostream &os, const vector &vec)->ostream& { os << vec[0]; for (size_t i = 1; i < vec.size(); i++) { os << ' ' << vec[i]; } os << '\n'; return os; } template auto operator>>(istream &is, vector &vec)->istream& { for (auto &i : vec) { is >> i; } return is; } template auto operator<<(ostream &os, const vector> &vec)->ostream& { for (auto &i : vec) { os << i[0]; for (size_t j = 1; j < i.size(); j++) { os << ' ' << i[j]; } os << '\n'; } return os; } template auto operator>>(istream &is, vector> &vec)->istream& { for (auto &i : vec) { for (auto &j : i) { is >> j; } } return is; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n; cin >> n; int time = 0; struct queryt { int a; int b; int l; int r; int type; int h; int i; }; V queries; vi rem; map var; vi ans; rep(i, n) { char op; cin >> op; if (op == '?') { int a, b; cin >> a >> b; var[a] = 0; var[b] = 0; ans.emplace_back(INT32_MAX >> 1); queries.emplace_back(a, b, time, time, 0, -1, ans.size() - 1); continue; } if (op == '+') { int a, b, h; cin >> a >> b >> h; var[a] = 0; var[b] = 0; time++; queries.emplace_back(a, b, time, INT32_MAX >> 1, 1, h, -1); rem.push_back(queries.size() - 1); continue; } int j; cin >> j; queries[rem[j - 1]].r = time; time++; } int v = 0; repv(i, var) { i.second = v; v += 2; } repv(i, queries) { i.a = var[i.a]; i.b = var[i.b]; } if (v > 1) { v = 1 << (32 - __builtin_clz(v - 1)); } vi seg(v << 1); vi lazy(v << 1); V upd(v << 1); vector> redo; redo.reserve(20 * v); auto persist = [&](int i) { redo.emplace_back(i, seg[i], lazy[i], upd[i]); }; auto propagate = [&](int i) { if (!upd[i]) { return; } persist(i); rmax(seg[i], lazy[i]); upd[i] = false; if (i < v) { int l = i << 1; int r = (i << 1) + 1; if (lazy[l] < lazy[i]) { persist(l); lazy[l] = lazy[i]; upd[l] = true; } if (lazy[r] < lazy[i]) { persist(r); lazy[r] = lazy[i]; upd[r] = true; } } }; function update = [&](int i, int l, int r, int tl, int tr, int v) { propagate(i); if (l > tr || r < tl) { return; } if (l >= tl && r <= tr) { if (lazy[i] >= v) { return; } persist(i); lazy[i] = v; upd[i] = true; propagate(i); return; } int mid = (l + r) >> 1; update(i * 2, l, mid, tl, tr, v); update(i * 2 + 1, mid + 1, r, tl, tr, v); int ans = min(seg[i * 2], seg[i * 2 + 1]); if (ans == seg[i]) { return; } persist(i); seg[i] = ans; }; function query = [&](int i, int l, int r, int tl, int tr) { propagate(i); if (l > tr || r < tl) { return INT32_MAX >> 1; } if (l >= tl && r <= tr) { return seg[i]; } int mid = (l + r) >> 1; return min(query(i * 2, l, mid, tl, tr), query(i * 2 + 1, mid + 1, r, tl, tr)); }; auto save = [&]() { redo.emplace_back(-1, -1, -1, -1); }; auto rollback = [&]() { while (get<0>(redo.back()) != -1) { auto [a, b, c, d] = redo.back(); redo.pop_back(); seg[a] = b; lazy[a] = c; upd[a] = d; } redo.pop_back(); }; function&)> func = [&](int l, int r, V queries) { if (l == r) { save(); repv(i, queries) { if (i.type == 1 && l >= i.l && l <= i.r) { update(1, 0, v - 1, i.a, i.b, i.h); } } repv(i, queries) { if (i.type == 0 && l == i.l) { rmin(ans[i.i], query(1, 0, v - 1, i.a, i.b)); } } rollback(); return; } save(); V queries2; repv(i, queries) { if (i.type == 1 && l >= i.l && r <= i.r) { update(1, 0, v - 1, i.a, i.b, i.h); continue; } if (l <= i.r && i.l <= r) { queries2.emplace_back(i); } } int mid = (l + r) >> 1; func(l, mid, queries2); func(mid + 1, r, queries2); rollback(); }; func(0, time, queries); repv(i, ans) { cout << i << '\n'; } }