結果
問題 |
No.3122 Median of Medians of Division
|
ユーザー |
![]() |
提出日時 | 2025-04-20 02:59:00 |
言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
結果 |
TLE
|
実行時間 | - |
コード長 | 3,675 bytes |
コンパイル時間 | 4,827 ms |
コンパイル使用メモリ | 329,244 KB |
実行使用メモリ | 426,668 KB |
最終ジャッジ日時 | 2025-04-20 02:59:14 |
合計ジャッジ時間 | 12,196 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
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; // Order-statistic tree for pairs (value, unique_id) to allow duplicates using OST = tree<pair<int,int>, null_type, less<pair<int,int>>, rb_tree_tag, tree_order_statistics_node_update>; // Fenwick tree of OSTs supporting point updates and range count_ge queries struct Fenwick { int n; vector<OST> bit; Fenwick(int _n): n(_n), bit(n+1) {} // add==true -> insert val; add==false -> erase val void update(int idx, const pair<int,int>& val, bool add) { for (; idx <= n; idx += idx & -idx) { if (add) bit[idx].insert(val); else bit[idx].erase(val); } } // count >= x in prefix [1..idx] int prefix_count_ge(int idx, int x) { int res = 0; pair<int,int> key = {x, INT_MIN}; for (; idx > 0; idx -= idx & -idx) { int sz = bit[idx].size(); int less = bit[idx].order_of_key(key); res += sz - less; } return res; } // count >= x in [l..r] int range_count_ge(int l, int r, int x) { if (l > r) return 0; return prefix_count_ge(r, x) - prefix_count_ge(l - 1, x); } }; struct Query { int type, a, b; }; int main() { ios::sync_with_stdio(false); cin.tie(NULL); int N, Q; cin >> N >> Q; vector<int> A(N+1); for (int i = 1; i <= N; i++) cin >> A[i]; vector<Query> queries(Q); for (int i = 0; i < Q; i++) cin >> queries[i].type >> queries[i].a >> queries[i].b; // Fenwicks for A, D1=min(A[i],A[i+1]), E=max(A[i],A[i+1]) Fenwick ftA(N), ftD1(max(N-1,1)), ftE(max(N-1,1)); // build initial for (int i = 1; i <= N; i++) ftA.update(i, {A[i], i}, true); for (int i = 1; i < N; i++) { int d1 = min(A[i], A[i+1]); int e = max(A[i], A[i+1]); ftD1.update(i, {d1, i}, true); ftE.update(i, {e, i}, true); } auto delAdj = [&](int pos) { if (pos < 1 || pos >= N) return; int old_d1 = min(A[pos], A[pos+1]); int old_e = max(A[pos], A[pos+1]); ftD1.update(pos, {old_d1, pos}, false); ftE.update(pos, {old_e, pos}, false); }; auto updAdj = [&](int pos) { if (pos < 1 || pos >= N) return; int new_d1 = min(A[pos], A[pos+1]); int new_e = max(A[pos], A[pos+1]); ftD1.update(pos, {new_d1, pos}, true); ftE.update(pos, {new_e, pos}, true); }; auto check = [&](int m, int l, int r) { int len = r - l + 1; int ones = ftA.range_count_ge(l, r, m); int a = ftD1.range_count_ge(l, r - 1, m); int total_pairs = r - l; int z = total_pairs - ftE.range_count_ge(l, r - 1, m); int left_zero = (A[l] < m ? 1 : 0); int seg0 = ((len) - a - z + left_zero) / 2; return ones > seg0; }; for (auto &q : queries) { if (q.type == 1) { int i = q.a, newv = q.b; ftA.update(i, {A[i], i}, false); ftA.update(i, {newv, i}, true); delAdj(i - 1); delAdj(i); A[i] = newv; updAdj(i - 1); updAdj(i); } else { int l = q.a, r = q.b; int lo = 1, hi = 1000000001, ans = 1; while (lo <= hi) { int mid = lo + (hi - lo) / 2; if (check(mid, l, r)) { ans = mid; lo = mid + 1; } else hi = mid - 1; } cout << ans << '\n'; } } return 0; }