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
| #include <bits/stdc++.h> using namespace std; typedef long long LL; const int MAX_N = 100000 + 5; int n, m, a[MAX_N], b[MAX_N], tree[MAX_N << 2], tag[MAX_N << 2]; int op[MAX_N], opL[MAX_N], opR[MAX_N]; int pos; void makeTag(int u) { for (int i = 1; i <= n; ++i) b[i] = (a[i] > u ? 1 : 0); } inline int ls(int o) { return o << 1; } inline int rs(int o) { return o << 1 | 1; } inline void pushUp(int o) { tree[o] = tree[ls(o)] + tree[rs(o)]; } inline void pushDown(int o, int l, int r) { if (tag[o] == -1) return; tag[ls(o)] = tag[rs(o)] = tag[o]; int mid = (l + r) >> 1; tree[ls(o)] = tag[o] * (mid - l + 1); tree[rs(o)] = tag[o] * (r - mid); tag[o] = -1; } void build(int o, int l, int r) { tag[o] = -1; if (l == r) { tree[o] = b[l]; return; } int mid = (l + r) >> 1; build(ls(o), l, mid); build(rs(o), mid + 1, r); pushUp(o); } void update(int o, int l, int r, int L, int R, int v) { if (L <= l && r <= R) { tag[o] = v; tree[o] = v * (r - l + 1); return; } int mid = (l + r) >> 1; pushDown(o, l, r); if (L <= mid) update(ls(o), l, mid, L, R, v); if (R > mid) update(rs(o), mid + 1, r, L, R, v); pushUp(o); } int query(int o, int l, int r, int L, int R) { if (L <= l && r <= R) return tree[o]; int mid = (l + r) >> 1, ret = 0; pushDown(o, l, r); if (L <= mid) ret += query(ls(o), l, mid, L, R); if (R > mid) ret += query(rs(o), mid + 1, r, L, R); return ret; } int main() { scanf("%d%d", &n, &m); for (int i = 1; i <= n; ++i) scanf("%d", a + i); for (int i = 1; i <= m; ++i) scanf("%d%d%d", op + i, opL + i, opR + i); scanf("%d", &pos); int l = 1, r = n; while (l < r) { int mid = (l + r) >> 1; makeTag(mid); build(1, 1, n); for (int i = 1; i <= m; ++i) { int sum = query(1, 1, n, opL[i], opR[i]); switch (op[i]) { case 0: { int k = opR[i] - sum + 1; if (opL[i] <= k - 1) update(1, 1, n, opL[i], k - 1, 0); if (opR[i] >= k) update(1, 1, n, k, opR[i], 1); break; } case 1: { int k = opL[i] + sum - 1; if (opL[i] <= k) update(1, 1, n, opL[i], k, 1); if (opR[i] >= k + 1) update(1, 1, n, k + 1, opR[i], 0); break; } } } if (query(1, 1, n, pos, pos)) l = mid + 1; else r = mid; } printf("%d\n", l); return 0; }
|