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
| #define int long long using namespace std;
const int N = 1e5 + 66;
inline void up(int p) { int l = p << 1, r = (p << 1) | 1; return (void)(tree[p].dat = tree[l].dat + tree[r].dat); }
inline void down(int p) { if (! tree[p].tag) return; int l = p << 1, r = (p << 1) | 1, c = tree[p].tag; tree[l].tag = tree[r].tag = c; if (tree[p].tag == 1) tree[l].dat = tree[r].dat = 0; else tree[l].dat = tree[l].len, tree[r].dat = tree[r].len; return (void)(tree[p].tag = 0); }
inline void build(int p, int l, int r, int k) { tree[p].len = (r - l + 1); if (l == r) return (void)(tree[p].dat = (a[l] >= k)); int mid = (l + r) >> 1; build(p << 1, l, mid, k), build((p << 1) | 1, mid + 1, r, k); return (void)(up(p)); }
inline void updata(int p, int l, int r, int nl, int nr, int k) { if (nl <= l && nr >= r) { tree[p].tag = k + 1; tree[p].dat = tree[p].len * k; return; } down(p); int mid = (l + r) >> 1; if (nl <= mid) updata(p << 1, l, mid, nl, nr, k); if (nr > mid) updata((p << 1) | 1, mid + 1, r, nl, nr, k); return (void)(up(p)); }
inline bool query(int p, int l, int r, int x) { if (l == r) return tree[p].dat == 1; down(p); int mid = (l + r) >> 1; if (x <= mid) return query(p << 1, l, mid, x); return query((p << 1) | 1, mid + 1, r, x); }
inline int query(int p, int l, int r, int nl, int nr) { if (nl <= l && nr >= r) return tree[p].dat; down(p); int mid = (l + r) >> 1, res(0); if (nl <= mid) res = query(p << 1, l, mid, nl, nr); if (nr > mid) res += query((p << 1) | 1, mid + 1, r, nl, nr); return res; }
inline bool pd(int k) { memset(&tree, 0, sizeof tree); build(1, 1, n, k); for (int i = 1; i <= m; ++ i) { int cnt = query(1, 1, n, le[i], ri[i]); if (cnt == 0 || cnt == ri[i] - le[i] + 1) continue; if (opt[i] == 0) { updata(1, 1, n, le[i], ri[i] - cnt, 0); updata(1, 1, n, ri[i] - cnt + 1, ri[i], 1); } else { updata(1, 1, n, le[i], le[i] + cnt - 1, 1); updata(1, 1, n, le[i] + cnt, ri[i], 0); } } return query(1, 1, n, q); }
signed main() { { n = read(), m = read(); for (int i = 1; i <= n; ++ i) a[i] = read(); for (int i = 1; i <= m; ++ i) opt[i] = read(), le[i] = read(), ri[i] = read(); q = read(); } { int l = 1, r = n, mid, res; while (l < r) { mid = (l + r + 1) >> 1; if (pd(mid)) l = mid; else r = mid - 1; } put(l); } return 0; }
|