結果
| 問題 | No.875 Range Mindex Query |
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2019-09-28 12:45:18 |
| 言語 | C++17(clang) (17.0.6 + boost 1.89.0) |
| 結果 |
AC
|
| 実行時間 | 96 ms / 2,000 ms |
| コード長 | 3,474 bytes |
| 記録 | |
| コンパイル時間 | 1,293 ms |
| コンパイル使用メモリ | 143,988 KB |
| 実行使用メモリ | 6,272 KB |
| 最終ジャッジ日時 | 2024-11-30 15:00:59 |
| 合計ジャッジ時間 | 2,988 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 |
| other | AC * 18 |
ソースコード
#include <iostream>
#include <algorithm>
#include <array>
#include <bitset>
#include <cstring>
#include <map>
#include <stack>
#include <set>
#include <tuple>
#include <queue>
#include <vector>
#include <cmath>
#include <random>
#include <math.h>
#include <random>
#include <functional>
#define REP(i, n) for(int (i) = 0; (i) < (n); ++(i))
#define rREP(i, n) for(int (i) = (n) - 1; (i) >= 0; --(i))
#define ALL(TheArray) TheArray.begin(), TheArray.end()
using lli = long long int;
using pii = std::pair<int, int>;
template <class T> inline bool chmax(T& a, T b){
if(a < b){a = b; return true;}
return false;
}
template <class T> inline bool chmin(T& a, T b){
if(a > b){a = b; return true;}
return false;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// モノイドの単位元と演算子を格納する抽象クラス (これはテンプレ)
template <typename T>
struct Monoid{
static constexpr T identity_element;
static constexpr T operation(T a, T b);
};
template<typename ValType, typename theMonoid>
class SegmentTree{
#define rep(i, n) for(int (i) = 0; (i) < (n); ++(i))
const int N; // 長さ 2の冪乗
const int n; // 元の配列の長さ
std::vector<ValType> node; // セグメント木本体
int computeLength(int m){
int res = 1; while(res < m) res <<= 1;
return res;
}
ValType preGetValue(int a, int b, int k, int l, int r){
if(r <= a or b <= l) return theMonoid::identity_element;
if(a <= l and r <= b) return node[k];
ValType vl = preGetValue(a, b, 2*k+1, l, (l+r)/2);
ValType vr = preGetValue(a, b, 2*k+2, (l+r)/2, r);
return theMonoid::operation(vl, vr);
}
public:
// コンストラクタ
SegmentTree(std::vector<ValType>& V): n(V.size()), N( computeLength(V.size()) ){
node.resize(2 * N - 1);
int i;
for(i = 0; i < n; ++i) node[i + N - 1] = V[i];
for(i = n; i < N; ++i) node[i + N - 1] = theMonoid::identity_element;
for(i = N - 2;i >= 0; --i)
node[i] = theMonoid::operation(node[2*i+1], node[2*i+2]);
}
// x番目の値をvalに変更する関数
bool update(int x, ValType val){
if(x < 0 or x >= n) return false;
int y = x + N - 1;
node[y] = val;
while(y > 0){
(--y) >>= 1;
node[y] = theMonoid::operation(node[2*y+1], node[2*y+2]);
}
return true;
}
// 元の配列の idx (0-indexed) 番目の要素を得る関数
ValType at(int idx){return node[idx + N - 1];}
// [a, b) の範囲の値を得る関数
ValType getValue(int a, int b){
return preGetValue(a, b, 0, 0, N);
}
#undef rep
};
struct TheMonoid{
static constexpr pii identity_element{INT32_MAX, -1};
static constexpr pii operation(pii a, pii b){
return a > b ? b : a;
}
};
std::vector<pii> A;
int main(void){
int n, q; scanf("%d%d", &n, &q);
A.resize(n);
REP(i, n){ scanf("%d", &A[i].first); A[i].second = i; }
SegmentTree<pii, TheMonoid> SegTree(A);
while(q--){
int q, l, r; scanf("%d%d%d", &q, &l, &r); l--; r--;
if(q == 1){
pii a = SegTree.at(l);
pii b = SegTree.at(r);
SegTree.update(r, {a.first, r});
SegTree.update(l, {b.first, l});
}
else printf("%d\n", SegTree.getValue(l, r+1).second + 1);
}
return 0;
}