結果
| 問題 |
No.3122 Median of Medians of Division
|
| コンテスト | |
| ユーザー |
Yu_212
|
| 提出日時 | 2025-04-20 11:56:18 |
| 言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 5,687 bytes |
| コンパイル時間 | 4,461 ms |
| コンパイル使用メモリ | 289,532 KB |
| 実行使用メモリ | 17,468 KB |
| 最終ジャッジ日時 | 2025-04-20 11:56:39 |
| 合計ジャッジ時間 | 19,886 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | WA * 1 |
| other | AC * 1 WA * 39 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
// Segment Tree with half-open intervals [l, r):
// - point update: set A[pos] = value
// - range query: retrieve the maximum and second maximum in A[l..r)
struct Node {
int mx1, mx2;
Node(int a = INT_MIN, int b = INT_MIN) : mx1(a), mx2(b) {}
};
class SegTree {
private:
int n;
vector<Node> st;
// Merge two child nodes into parent
Node merge(const Node &L, const Node &R) {
Node res;
if (L.mx1 >= R.mx1) {
res.mx1 = L.mx1;
res.mx2 = max(L.mx2, R.mx1);
} else {
res.mx1 = R.mx1;
res.mx2 = max(R.mx2, L.mx1);
}
return res;
}
// build node p covering [l, r)
void build(int p, int l, int r, const vector<int> &A) {
if (r - l == 1) {
st[p] = Node(A[l], INT_MIN);
return;
}
int m = (l + r) >> 1;
build(p<<1, l, m, A);
build(p<<1|1, m, r, A);
st[p] = merge(st[p<<1], st[p<<1|1]);
}
// update position idx to val in node p covering [l, r)
void update(int p, int l, int r, int idx, int val) {
if (r - l == 1) {
st[p] = Node(val, INT_MIN);
return;
}
int m = (l + r) >> 1;
if (idx < m) update(p<<1, l, m, idx, val);
else update(p<<1|1, m, r, idx, val);
st[p] = merge(st[p<<1], st[p<<1|1]);
}
// query on [ql, qr) in node p covering [l, r)
Node query(int p, int l, int r, int ql, int qr) {
if (qr <= l || r <= ql) return Node();
if (ql <= l && r <= qr) return st[p];
int m = (l + r) >> 1;
Node L = query(p<<1, l, m, ql, qr);
Node R = query(p<<1|1, m, r, ql, qr);
return merge(L, R);
}
public:
// Initialize with array A (0-based)
SegTree(const vector<int> &A) {
n = A.size();
st.assign(4*n, Node());
build(1, 0, n, A);
}
// Point update: A[pos] = val
void update(int pos, int val) {
if (pos < 0 || pos >= n) return;
update(1, 0, n, pos, val);
}
// Range query [l, r): returns Node with mx1, mx2
Node query(int l, int r) {
if (l < 0) l = 0;
if (r > n) r = n;
if (l >= r) return Node();
return query(1, 0, n, l, r);
}
};
// 2) Segment Tree for minimum on even and odd indices on half-open intervals [l, r)
struct NodeMin {
int min_even, min_odd;
NodeMin(int me = INT_MAX, int mo = INT_MAX) : min_even(me), min_odd(mo) {}
};
class SegTreeMinParity {
private:
int n;
vector<NodeMin> st;
NodeMin merge(const NodeMin &L, const NodeMin &R) const {
return NodeMin(
min(L.min_even, R.min_even),
min(L.min_odd, R.min_odd)
);
}
void build(int p, int l, int r, const vector<int> &A) {
if (r - l == 1) {
int me = (l % 2 == 0 ? A[l] : INT_MAX);
int mo = (l % 2 == 1 ? A[l] : INT_MAX);
st[p] = NodeMin(me, mo);
return;
}
int m = (l + r) >> 1;
build(p<<1, l, m, A);
build(p<<1|1, m, r, A);
st[p] = merge(st[p<<1], st[p<<1|1]);
}
void update(int p, int l, int r, int idx, int val) {
if (r - l == 1) {
int me = (l % 2 == 0 ? val : INT_MAX);
int mo = (l % 2 == 1 ? val : INT_MAX);
st[p] = NodeMin(me, mo);
return;
}
int m = (l + r) >> 1;
if (idx < m) update(p<<1, l, m, idx, val);
else update(p<<1|1, m, r, idx, val);
st[p] = merge(st[p<<1], st[p<<1|1]);
}
NodeMin query(int p, int l, int r, int ql, int qr) const {
if (qr <= l || r <= ql) return NodeMin();
if (ql <= l && r <= qr) return st[p];
int m = (l + r) >> 1;
NodeMin L = query(p<<1, l, m, ql, qr);
NodeMin R = query(p<<1|1, m, r, ql, qr);
return merge(L, R);
}
public:
SegTreeMinParity(const vector<int> &A) {
n = A.size();
st.assign(4*n, NodeMin());
build(1, 0, n, A);
}
void update(int pos, int val) {
if (pos < 0 || pos >= n) return;
update(1, 0, n, pos, val);
}
NodeMin query(int l, int r) const {
if (l < 0) l = 0;
if (r > n) r = n;
if (l >= r) return NodeMin();
return query(1, 0, n, l, r);
}
};
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int N, Q;
cin >> N >> Q;
vector<int> A(N);
for (int i = 0; i < N; i++) cin >> A[i];
vector<int> B(N-1);
for (int i = 0; i < N-1; i++) {
B[i] = min(A[i], A[i+1]);
}
SegTree st(B);
SegTreeMinParity stMin(A);
while (Q--) {
int type;
cin >> type;
if (type == 1) {
int idx, x;
cin >> idx >> x;
idx--;
A[idx] = x;
if (idx > 0) {
B[idx-1] = min(A[idx], A[idx-1]);
st.update(idx-1, B[idx-1]);
}
if (idx < N-1) {
B[idx] = min(A[idx], A[idx+1]);
st.update(idx, B[idx]);
}
stMin.update(idx, A[idx]);
} else if (type == 2) {
int l, r;
cin >> l >> r;
l--;
NodeMin mn = stMin.query(l, r);
int ans = 0;
if (l % 2 == 0) ans = max(ans, mn.min_even);
if (l % 2 == 1) ans = max(ans, mn.min_odd);
Node res = st.query(l, r-1);
ans = max(ans, min(res.mx1, max(A[l], A[r-1])));
ans = max(ans, res.mx2);
cout << ans << endl;
}
}
return 0;
}
Yu_212