#include #include #include #include using namespace std; const int MAX_VAL = 1 << 24; const int D_SIZE = 20000005; // --- 高速ヒルベルト順序計算 (反復版) --- inline long long get_hilbert(int x, int y) { long long d = 0; // 2^19 は約 524,288 なので N=10^5 程度なら十分。必要に応じて調整 for (int s = 1 << 19; s > 0; s >>= 1) { bool rx = x & s; bool ry = y & s; d += s * 1LL * s * ((3 * rx) ^ ry); if (!ry) { if (rx) { x = (1 << 20) - 1 - x; y = (1 << 20) - 1 - y; } swap(x, y); } } return d; } // HierarchicalBitset の実装は変更なし(addの早期終了のみ維持) struct HierarchicalBitset { vector layers[4]; HierarchicalBitset() { layers[0].resize(1); layers[1].resize(64); layers[2].resize(4096); layers[3].resize(262144); } inline void add(int a) { for (int i = 3; i >= 0; --i) { int a0 = a & 63; a >>= 6; if (layers[i][a] & (1ULL << a0)) return; // 既に立っていれば終了 layers[i][a] |= (1ULL << a0); } } inline void dec(int a) { for (int i = 3; i >= 0; --i) { int a0 = a & 63; a >>= 6; layers[i][a] ^= (1ULL << a0); if (layers[i][a]) break; } } int bsl(int a) { if (a < 0) return -1; for (int i = 3; i >= 0; --i) { uint64_t mask = (1ULL << (a & 63)) | ((1ULL << (a & 63)) - 1); uint64_t x = layers[i][a >> 6] & mask; if (x) { int rep = ((a >> 6) << 6) | (63 - __builtin_clzll(x)); for (int j = i + 1; j < 4; ++j) { rep = (rep << 6) | (63 - __builtin_clzll(layers[j][rep])); } return rep; } a = (a >> 6) - 1; if (a < 0) break; } return -1; } int bsr(int a) { if (a >= MAX_VAL) return -1; for (int i = 3; i >= 0; --i) { uint64_t mask = ~((1ULL << (a & 63)) - 1); uint64_t x = layers[i][a >> 6] & mask; if (x) { int rep = ((a >> 6) << 6) | __builtin_ctzll(x); for (int j = i + 1; j < 4; ++j) { rep = (rep << 6) | __builtin_ctzll(layers[j][rep]); } return rep; } a = (a >> 6) + 1; if (a >= (1 << (6 * i))) break; } return -1; } }; int D[D_SIZE]; int cnt0 = 0; HierarchicalBitset X, Y; // f0, f1 のロジックは変更なし void f0(int a) { D[a]++; if (D[a] > 1) { cnt0++; return; } int al = X.bsl(a - 1); int ar = X.bsr(a + 1); X.add(a); if (al != -1 && ar != -1) { int diff = ar - al; if (--D[10000000 + diff] == 0) Y.dec(diff); } if (al != -1) { int diff = a - al; if (++D[10000000 + diff] == 1) Y.add(diff); } if (ar != -1) { int diff = ar - a; if (++D[10000000 + diff] == 1) Y.add(diff); } } void f1(int a) { D[a]--; if (D[a] > 0) { cnt0--; return; } X.dec(a); int al = X.bsl(a - 1); int ar = X.bsr(a + 1); if (al != -1 && ar != -1) { int diff = ar - al; if (++D[10000000 + diff] == 1) Y.add(diff); } if (al != -1) { int diff = a - al; if (--D[10000000 + diff] == 0) Y.dec(diff); } if (ar != -1) { int diff = ar - a; if (--D[10000000 + diff] == 0) Y.dec(diff); } } struct Query { int t, l, r, x, id; long long ord; // ヒルベルト順序を格納 }; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n, q; if (!(cin >> n >> q)) return 0; vector A(n); for (int i = 0; i < n; ++i) cin >> A[i]; vector queries(q); for (int i = 0; i < q; ++i) { string c; cin >> queries[i].l >> queries[i].r >> queries[i].x >> c; queries[i].l--; // 0-indexed queries[i].t = (c == "L" ? 0 : 1); queries[i].id = i; // クエリごとにヒルベルト順序を計算 queries[i].ord = get_hilbert(queries[i].l, queries[i].r); } // ヒルベルト順序でソート sort(queries.begin(), queries.end(), [](const Query& a, const Query& b) { return a.ord < b.ord; }); vector ans(q); int nl = 0, nr = 0; for (auto& qry : queries) { while (qry.l < nl) f0(A[--nl]); while (nr < qry.r) f0(A[nr++]); while (nl < qry.l) f1(A[nl++]); while (qry.r < nr) f1(A[--nr]); if (qry.t == 0) { int res = Y.bsl(qry.x); ans[qry.id] = (cnt0 > 0) ? max(res, 0) : res; } else { ans[qry.id] = Y.bsr(qry.x); } } for (int x : ans) cout << x << "\n"; return 0; }