結果
問題 |
No.3122 Median of Medians of Division
|
ユーザー |
|
提出日時 | 2025-04-20 19:46:53 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
TLE
|
実行時間 | - |
コード長 | 2,632 bytes |
コンパイル時間 | 2,782 ms |
コンパイル使用メモリ | 211,500 KB |
実行使用メモリ | 24,160 KB |
最終ジャッジ日時 | 2025-04-20 19:47:04 |
合計ジャッジ時間 | 11,206 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | -- * 1 |
other | TLE * 1 -- * 39 |
ソースコード
#include <bits/stdc++.h> using namespace std; const int BLOCK = 450; // √N程度 struct Query { int l, r, time, id; bool operator<(const Query& other) const { if (l / BLOCK != other.l / BLOCK) return l < other.l; if (r / BLOCK != other.r / BLOCK) return r < other.r; return time < other.time; } }; vector<int> A, original; vector<pair<int, int>> updates; multiset<int> leftSet, rightSet; void balance() { while (leftSet.size() > rightSet.size()) { auto it = prev(leftSet.end()); rightSet.insert(*it); leftSet.erase(it); } while (rightSet.size() > leftSet.size() + 1) { auto it = rightSet.begin(); leftSet.insert(*it); rightSet.erase(it); } } void add(int x) { if (rightSet.empty() || x >= *rightSet.begin()) rightSet.insert(x); else leftSet.insert(x); balance(); } void remove(int x) { if (rightSet.find(x) != rightSet.end()) rightSet.erase(rightSet.find(x)); else leftSet.erase(leftSet.find(x)); balance(); } void applyUpdate(int idx, int newValue, int& oldValue) { oldValue = A[idx]; remove(oldValue); A[idx] = newValue; add(newValue); } void revertUpdate(int idx, int oldValue) { remove(A[idx]); A[idx] = oldValue; add(oldValue); } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int N, Q; cin >> N >> Q; A.resize(N); for (int i = 0; i < N; i++) cin >> A[i]; vector<Query> queries; vector<int> answers(Q); int nowTime = 0; for (int i = 0; i < Q; i++) { int type, a, b; cin >> type >> a >> b; if (type == 1) { updates.emplace_back(a - 1, b); } else { queries.push_back({a - 1, b - 1, (int)updates.size(), i}); } } sort(queries.begin(), queries.end()); int l = 0, r = -1, t = 0; original = A; for (auto& q : queries) { while (t < q.time) { int idx = updates[t].first, val = updates[t].second, old; applyUpdate(idx, val, old); updates[t].second = old; // old値を保存 t++; } while (t > q.time) { t--; int idx = updates[t].first, old = updates[t].second; revertUpdate(idx, old); } while (r < q.r) add(A[++r]); while (l > q.l) add(A[--l]); while (r > q.r) remove(A[r--]); while (l < q.l) remove(A[l++]); answers[q.id] = *rightSet.begin(); // 中央値は右側先頭 } for (int i = 0; i < Q; i++) { if (answers[i]) cout << answers[i] << '\n'; } }