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 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
| #include <bits/stdc++.h>
#define int int64_t
const int kMaxN = 2.5e5 + 5;
int n, m, q; int op[kMaxN], L[kMaxN], R[kMaxN], C[kMaxN], K[kMaxN], ans[kMaxN]; std::vector<std::pair<int, int>> vec[kMaxN];
struct SGT { int cnt[kMaxN * 4], sum[kMaxN * 4], mi[kMaxN * 4], pos[kMaxN * 4];
void pushup(int x) { cnt[x] = cnt[x << 1] + cnt[x << 1 | 1]; sum[x] = sum[x << 1] + sum[x << 1 | 1]; if (mi[x << 1] < sum[x << 1] + mi[x << 1 | 1]) { mi[x] = mi[x << 1], pos[x] = pos[x << 1]; } else { mi[x] = sum[x << 1] + mi[x << 1 | 1], pos[x] = pos[x << 1 | 1]; } }
void build(int x, int l, int r) { pos[x] = l; if (l == r) return; int mid = (l + r) >> 1; build(x << 1, l, mid), build(x << 1 | 1, mid + 1, r); }
void update(int x, int l, int r, int ql, int v) { if (l == r) { if (v == 1) { if (op[l] == 1) cnt[x] = sum[x] = mi[x] = K[l]; else cnt[x] = 0, sum[x] = mi[x] = -K[l]; } else { cnt[x] = sum[x] = mi[x] = 0; } return; } int mid = (l + r) >> 1; if (ql <= mid) update(x << 1, l, mid, ql, v); else update(x << 1 | 1, mid + 1, r, ql, v); pushup(x); }
std::tuple<int, int, int> querymin(int x, int l, int r, int ql, int qr) { if (l > qr || r < ql) return {0, 0, 0}; else if (l >= ql && r <= qr) return {sum[x], mi[x], pos[x]}; int mid = (l + r) >> 1; if (qr <= mid) return querymin(x << 1, l, mid, ql, qr); if (mid < ql) return querymin(x << 1 | 1, mid + 1, r, ql, qr); auto [suml, mil, posl] = querymin(x << 1, l, mid, ql, qr); auto [sumr, mir, posr] = querymin(x << 1 | 1, mid + 1, r, ql, qr); if (mil <= suml + mir) return {suml + sumr, mil, posl}; else return {suml + sumr, suml + mir, posr}; }
int querysum(int x, int l, int r, int ql, int qr) { if (l > qr || r < ql) return 0; else if (l >= ql && r <= qr) return sum[x]; int mid = (l + r) >> 1; return querysum(x << 1, l, mid, ql, qr) + querysum(x << 1 | 1, mid + 1, r, ql, qr); }
int querycnt(int x, int l, int r, int ql, int qr) { if (l > qr || r < ql) return 0; else if (l >= ql && r <= qr) return cnt[x]; int mid = (l + r) >> 1; return querycnt(x << 1, l, mid, ql, qr) + querycnt(x << 1 | 1, mid + 1, r, ql, qr); }
int querykth(int x, int l, int r, int k) { assert(k <= cnt[x]); if (l == r) return C[l]; int mid = (l + r) >> 1; if (k <= cnt[x << 1]) return querykth(x << 1, l, mid, k); else return querykth(x << 1 | 1, mid + 1, r, k - cnt[x << 1]); } } sgt;
void dickdreamer() { std::cin >> n >> m >> q; for (int i = 1; i <= q; ++i) { std::cin >> op[i]; if (op[i] == 1) { std::cin >> L[i] >> R[i] >> C[i] >> K[i]; vec[L[i]].emplace_back(i, 1), vec[R[i] + 1].emplace_back(i, -1); } else if (op[i] == 2) { std::cin >> L[i] >> R[i] >> K[i]; vec[L[i]].emplace_back(i, 1), vec[R[i] + 1].emplace_back(i, -1); } else { std::cin >> C[i] >> K[i]; vec[C[i]].emplace_back(i, K[i]); } } sgt.build(1, 0, q); for (int i = 1; i <= n; ++i) { for (auto [id, v] : vec[i]) { if (op[id] == 1 || op[id] == 2) sgt.update(1, 0, q, id, v); } for (auto [id, v] : vec[i]) { if (op[id] != 3) continue; int pos = std::get<2>(sgt.querymin(1, 0, q, 0, id)); int cnt = sgt.querysum(1, 0, q, pos + 1, id), tot = sgt.querycnt(1, 0, q, 0, id); if (cnt >= K[id]) ans[id] = sgt.querykth(1, 0, q, tot - cnt + K[id]); } } for (int i = 1; i <= q; ++i) if (op[i] == 3) std::cout << ans[i] << '\n'; }
int32_t main() { #ifdef ORZXKR freopen("in.txt", "r", stdin); freopen("out.txt", "w", stdout); #endif std::ios::sync_with_stdio(0), std::cin.tie(0), std::cout.tie(0); int T = 1; while (T--) dickdreamer(); return 0; }
|