結果
問題 | No.875 Range Mindex Query |
ユーザー |
![]() |
提出日時 | 2024-11-26 11:38:00 |
言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 66 ms / 2,000 ms |
コード長 | 3,891 bytes |
コンパイル時間 | 3,033 ms |
コンパイル使用メモリ | 252,948 KB |
実行使用メモリ | 6,400 KB |
最終ジャッジ日時 | 2024-11-26 11:38:06 |
合計ジャッジ時間 | 4,511 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 1 |
other | AC * 18 |
ソースコード
#include <bits/stdc++.h>using namespace std;using ll = long long;#ifdef LOCAL#include <debug.hpp>#else#define debug(...)#endiftemplate <class T, class F>struct SegmentTree {int n, len;vector<T> data;const F op;const T e;SegmentTree() = default;SegmentTree(int size, const F& operation, const T& identify) : n(size), op(operation), e(identify) { init(); }SegmentTree(const vector<T>& A, const F& operation, const T& identify): n(int(A.size())), op(operation), e(identify) {init(), build(A);}void init() {len = 1;while (len < n) len <<= 1;data.assign(len << 1, e);}void build(const vector<T>& A) {for (int i = 0; i < n; i++) data[i + len] = A[i];for (int i = len - 1; i > 0; i--) data[i] = op(data[i << 1 | 0], data[i << 1 | 1]);}void update(int i, T x) {i += len, data[i] = x;while (i > 1) {i >>= 1;data[i] = op(data[i << 1 | 0], data[i << 1 | 1]);}}void add(int i, T x) {i += len, data[i] += x;while (i > 1) {i >>= 1;data[i] = op(data[i << 1 | 0], data[i << 1 | 1]);}}T prod(int l, int r) const {l += len, r += len;T resl = e, resr = e;while (l < r) {if (l & 1) resl = op(resl, data[l++]);if (r & 1) resr = op(data[--r], resr);l >>= 1, r >>= 1;}return op(resl, resr);}T all_prod() const { return data[1]; }T operator[](int i) const { return data[i + len]; }// check(A[l] * ... * A[r - 1]) = true となる最大の rtemplate <class C>int max_right(int l, const C& check) const {assert(0 <= l && l <= n && check(e));if (l == n) return n;l += len;T sum = e;do {while (l % 2 == 0) l >>= 1;if (!check(op(sum, data[l]))) {while (l < len) {l = l << 1 | 0;if (check(op(sum, data[l]))) {sum = op(sum, data[l++]);}}return l - len;}sum = op(sum, data[l++]);} while ((l & -l) != l);return n;}// check(A[l] * ... * A[r - 1]) = true となる最小の ltemplate <class C>int min_left(int r, const C& check) const {assert(0 <= r && r <= n && check(e));if (r == 0) return 0;r += len;T sum = e;do {--r;while (r > 1 && r % 2) r >>= 1;if (!check(op(data[r], sum))) {while (r < len) {r = r << 1 | 1;if (check(op(data[r], sum))) {sum = op(data[r--], sum);}}return r + 1 - len;}sum = op(data[r], sum);} while ((r & -r) != r);return 0;}};int main() {cin.tie(nullptr);ios::sync_with_stdio(false);cout << fixed << setprecision(20);int N, Q;cin >> N >> Q;vector<int> A(N);for (int i = 0; i < N; i++) cin >> A[i];// {value, index}using T = pair<int, int>;auto op = [](T a, T b) { return a.first < b.first ? a : b; };constexpr T e = {numeric_limits<int>::max(), -1};vector<T> V(N);for (int i = 0; i < N; i++) V[i] = {A[i], i};SegmentTree<T, decltype(op)> seg(V, op, e);while (Q--) {int t, l, r;cin >> t >> l >> r, l--, r--;if (t == 1) {auto [lv, lid] = seg[l];auto [rv, rid] = seg[r];seg.update(l, {rv, lid}), seg.update(r, {lv, rid});}if (t == 2) {cout << seg.prod(l, r + 1).second + 1 << '\n';}}}