結果
| 問題 |
No.3122 Median of Medians of Division
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2025-04-19 14:54:04 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 2,842 bytes |
| コンパイル時間 | 2,774 ms |
| コンパイル使用メモリ | 237,032 KB |
| 実行使用メモリ | 333,976 KB |
| 最終ジャッジ日時 | 2025-04-19 14:54:16 |
| 合計ジャッジ時間 | 11,483 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | -- * 1 |
| other | TLE * 1 -- * 39 |
ソースコード
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using ll = long long;
using namespace __gnu_pbds;
// ordered multiset storing (value_id, position)
using OS = tree<pair<int,int>, null_type, less<pair<int,int>>, rb_tree_tag, tree_order_statistics_node_update>;
int N, Q;
vector<int> A;
vector<int> vals;
vector<OS> seg;
// Update segment tree: remove old pair (-1,-1) if oldv.first==-1 skip erase
void update_tree(int idx, int l, int r, int pos, const pair<int,int>& oldv, const pair<int,int>& newv) {
if (oldv.first != -1) seg[idx].erase(oldv);
seg[idx].insert(newv);
if (l == r) return;
int mid = (l + r) >> 1;
if (pos <= mid) update_tree(idx<<1, l, mid, pos, oldv, newv);
else update_tree(idx<<1|1, mid+1, r, pos, oldv, newv);
}
// Query k-th smallest in [ql, qr]
int query_kth(int idx, int l, int r, int ql, int qr, int k) {
if (l == r) return l;
int mid = (l + r) >> 1;
// count elements in left child within [ql,qr]
auto &osl = seg[idx<<1];
int cnt = osl.order_of_key({qr+1, -1}) - osl.order_of_key({ql, -1});
if (cnt >= k) return query_kth(idx<<1, l, mid, ql, qr, k);
else return query_kth(idx<<1|1, mid+1, r, ql, qr, k - cnt);
}
struct Query { int t, i, x, l, r; };
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> N >> Q;
A.resize(N);
vals.reserve(N + Q);
for (int i = 0; i < N; i++) {
cin >> A[i];
vals.push_back(A[i]);
}
vector<Query> qs(Q);
for (int qi = 0; qi < Q; qi++) {
cin >> qs[qi].t;
if (qs[qi].t == 1) {
cin >> qs[qi].i >> qs[qi].x;
--qs[qi].i;
vals.push_back(qs[qi].x);
} else {
cin >> qs[qi].l >> qs[qi].r;
--qs[qi].l; --qs[qi].r;
}
}
// compress
sort(vals.begin(), vals.end());
vals.erase(unique(vals.begin(), vals.end()), vals.end());
int M = vals.size();
auto getId = [&](int v){ return int(lower_bound(vals.begin(), vals.end(), v) - vals.begin()); };
// build segment tree nodes
seg.assign(4 * N, OS());
// insert initial values
for (int i = 0; i < N; i++) {
int vid = getId(A[i]);
update_tree(1, 0, N-1, i, {-1,-1}, {vid, i});
}
// process queries
for (auto &q : qs) {
if (q.t == 1) {
int idx = q.i;
int oldv = getId(A[idx]);
int newv = getId(q.x);
update_tree(1, 0, N-1, idx, {oldv, idx}, {newv, idx});
A[idx] = q.x;
} else {
int l = q.l, r = q.r;
int len = r - l + 1;
int k = (len + 1) >> 1;
int vid = query_kth(1, 0, N-1, l, r, k);
cout << vals[vid] << '\n';
}
}
return 0;
}