結果
問題 |
No.3122 Median of Medians of Division
|
ユーザー |
|
提出日時 | 2025-04-19 15:06:50 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
TLE
|
実行時間 | - |
コード長 | 4,605 bytes |
コンパイル時間 | 2,686 ms |
コンパイル使用メモリ | 213,588 KB |
実行使用メモリ | 155,844 KB |
最終ジャッジ日時 | 2025-04-19 15:07:05 |
合計ジャッジ時間 | 11,007 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | -- * 1 |
other | TLE * 2 -- * 38 |
ソースコード
#include <bits/stdc++.h> using namespace std; using ll = long long; // Merge Sort Tree + Fenwick per node struct Node { vector<int> pos; // sorted unique positions vector<int> bit; // Fenwick tree of size pos.size()+1 }; int N, Q; vector<int> A; vector<int> vals; // compressed values vector<Node> segtree; int M; // collect positions for vid along tree void collect(int idx, int l, int r, int vid, int p) { segtree[idx].pos.push_back(p); if (l == r) return; int mid = (l + r) >> 1; if (vid <= mid) collect(idx<<1, l, mid, vid, p); else collect(idx<<1|1, mid+1, r, vid, p); } // build Fenwick per node void build(int idx, int l, int r) { auto &node = segtree[idx]; auto &v = node.pos; sort(v.begin(), v.end()); v.erase(unique(v.begin(), v.end()), v.end()); node.bit.assign(v.size()+1, 0); if (l == r) return; int mid = (l + r) >> 1; build(idx<<1, l, mid); build(idx<<1|1, mid+1, r); } // Fenwick helpers inline void fenwicks_update(vector<int> &bit, int i, int d) { int n = bit.size(); for (; i < n; i += i & -i) bit[i] += d; } inline int fenwicks_sum(const vector<int> &bit, int i) { int s = 0; for (; i > 0; i -= i & -i) s += bit[i]; return s; } // update point p with delta at value vid void updatePoint(int idx, int l, int r, int vid, int p, int delta) { auto &node = segtree[idx]; int i = int(lower_bound(node.pos.begin(), node.pos.end(), p) - node.pos.begin()) + 1; fenwicks_update(node.bit, i, delta); if (l == r) return; int mid = (l + r) >> 1; if (vid <= mid) updatePoint(idx<<1, l, mid, vid, p, delta); else updatePoint(idx<<1|1, mid+1, r, vid, p, delta); } // count positions in [ql,qr] in node idx int countRange(int idx, int ql, int qr) { auto &node = segtree[idx]; auto &v = node.pos; int li = int(lower_bound(v.begin(), v.end(), ql) - v.begin()) + 1; int ri = int(upper_bound(v.begin(), v.end(), qr) - v.begin()); if (ri < li) return 0; return fenwicks_sum(node.bit, ri) - fenwicks_sum(node.bit, li-1); } // query k-th smallest valueID within positions [ql,qr] int queryKth(int idx, int l, int r, int ql, int qr, int k) { if (l == r) return l; int mid = (l + r) >> 1; int cnt = countRange(idx<<1, ql, qr); if (cnt >= k) return queryKth(idx<<1, l, mid, ql, qr, k); else return queryKth(idx<<1|1, mid+1, r, ql, qr, k - cnt); } 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<tuple<int,int,int,int,int>> queries(Q); for (int qi = 0; qi < Q; qi++) { int t; cin >> t; if (t == 1) { int i, x; cin >> i >> x; --i; queries[qi] = {t, i, x, 0, 0}; vals.push_back(x); } else { int l, r; cin >> l >> r; --l; --r; queries[qi] = {t, 0, 0, l, r}; } } // compress values sort(vals.begin(), vals.end()); vals.erase(unique(vals.begin(), vals.end()), vals.end()); M = vals.size(); auto getId = [&](int x){ return int(lower_bound(vals.begin(), vals.end(), x) - vals.begin()); }; // build segment tree structure over [0,M-1] segtree.assign(4 * M + 4, Node()); // collect positions: initial A for (int i = 0; i < N; i++) { int vid = getId(A[i]); collect(1, 0, M-1, vid, i); } // also collect for updates for (auto &q : queries) { int t = get<0>(q); if (t == 1) { int i = get<1>(q), x = get<2>(q); int vid = getId(x); collect(1, 0, M-1, vid, i); } } // build Fenwick trees build(1, 0, M-1); // initialize with initial A for (int i = 0; i < N; i++) { int vid = getId(A[i]); updatePoint(1, 0, M-1, vid, i, +1); } // answer queries for (auto &q : queries) { int t = get<0>(q); if (t == 1) { int i = get<1>(q), x = get<2>(q); int oldv = getId(A[i]); int newv = getId(x); if (oldv != newv) { updatePoint(1, 0, M-1, oldv, i, -1); updatePoint(1, 0, M-1, newv, i, +1); A[i] = x; } } else { int l = get<3>(q), r = get<4>(q); int len = r - l + 1; int k = (len + 1) >> 1; int vid = queryKth(1, 0, M-1, l, r, k); cout << vals[vid] << '\n'; } } return 0; }