結果
| 問題 |
No.878 Range High-Element Query
|
| コンテスト | |
| ユーザー |
yosupot
|
| 提出日時 | 2019-09-06 21:47:41 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 183 ms / 2,000 ms |
| コード長 | 1,807 bytes |
| コンパイル時間 | 2,512 ms |
| コンパイル使用メモリ | 196,764 KB |
| 最終ジャッジ日時 | 2025-01-07 16:46:11 |
|
ジャッジサーバーID (参考情報) |
judge2 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 |
| other | AC * 18 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template <class T> using V = vector<T>;
template <int S> struct SegTree {
static const int N = 1 << S;
struct Node {
int ma = -1, num = 0, rnum = 0;
};
V<Node> seg = V<Node>(2 * N);
SegTree() {}
void set(int k, int x) {
k += N;
seg[k] = {x, 1, 0};
while (k > 1) {
k /= 2;
update(k);
}
}
// lower_bound(seg[k], x)のイメージ
int find(int k, int x) {
if (k >= N) {
if (x >= seg[k].ma) return 0;
return 1;
}
if (x > seg[k * 2].ma) {
return find(k * 2 + 1, x);
} else {
return find(k * 2, x) + seg[k].rnum;
}
}
// n += node[k]
Node merge(Node n, int k) {
Node res;
res.ma = max(n.ma, seg[k].ma);
res.rnum = find(k, n.ma);
res.num = n.num + res.rnum;
return res;
}
void update(int k) {
assert(1 <= k && k < N);
seg[k] = merge(seg[k * 2], k * 2 + 1);
}
Node query(int a, int b, Node n = Node(), int l = 0, int r = N, int k = 1) {
if (a <= l && r <= b) {
return merge(n, k);
}
if (r <= a || b <= l) return n;
int md = (l + r) / 2;
n = query(a, b, n, l, md, 2 * k);
n = query(a, b, n, md, r, 2 * k + 1);
return n;
}
};
SegTree<17> st;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, q;
cin >> n >> q;
for (int i = 0; i < n; i++) {
int a;
cin >> a;
st.set(i, a);
}
for (int i = 0; i < q; i++) {
int ty, l, r;
cin >> ty >> l >> r; l--;
cout << st.query(l, r).num << "\n";
}
return 0;
}
yosupot