#include #include #include using namespace std; using i64 = long long; class SegTree { int n; vector v; vector p; // 場所 pair query(int a, int b, int k, int l, int r); public: const int INIT_VAL = 0; SegTree(int n); SegTree(const vector &w); static int min_pow2(const int n); // n以上の最小の "2の冪乗" static int calc_size(const int n); // 要素数 n の配列をセグメントツリーにするときのサイズ (min_pow2(n) x 2) を計算する void update(int i, int val); // 配列 w の i 番目 (0-indexed) を val にする。 pair query(int a, int b); // [a, b) の範囲 }; SegTree::SegTree(int n) : n(n), v(n, INIT_VAL) { v[0] = -1; } SegTree::SegTree(const vector &w) { int m = w.size(); n = calc_size(m); v.assign(n, INIT_VAL); p.assign(n, -1); v[0] = -1; p[0] = -1; for(int i=0; i>= 1; if(i == 0) { break; } if(v[i*2] < v[i*2+1]) { v[i] = v[i*2+1]; p[i] = p[i*2+1]; } else { v[i] = v[i*2]; p[i] = p[i*2]; } } } pair SegTree:: query(int a, int b, int k, int l, int r) { // [a, b) と [l, r) が交差しないとき if(r <= a || b <= l) { return make_pair(-1, INIT_VAL); } // [a, b) が [l, r) を完全に含んでいるとき if(a <= l && r <= b) { return make_pair(p[k], v[k]); } int pl, vl, pr, vr; tie(pl, vl) = query(a, b, 2*k, l, (l+r)/2), tie(pr, vr) = query(a, b, 2*k+1, (l+r)/2, r); if(vl < vr) { return make_pair(pr, vr); } return make_pair(pl, vl); } // [a, b) の範囲 (a, b は 0-indexed) pair SegTree:: query(int a, int b) { return query(a, b, 1, 0, n >> 1); } int SegTree::min_pow2(const int n) { int m = 1; while(m < n) { m <<= 1; } return m; } int SegTree::calc_size(const int n) { return min_pow2(n) << 1; } int main(void) { int n, d, k; scanf("%d%d%d", &n, &d, &k); vector x(n); // x[n] for(int i=0; i