結果
| 問題 |
No.3122 Median of Medians of Division
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2025-04-20 05:35:21 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 5,533 bytes |
| コンパイル時間 | 2,596 ms |
| コンパイル使用メモリ | 215,584 KB |
| 実行使用メモリ | 124,516 KB |
| 最終ジャッジ日時 | 2025-04-20 05:35:33 |
| 合計ジャッジ時間 | 11,352 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | -- * 1 |
| other | TLE * 1 -- * 39 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
struct Fenwick2D {
int M;
vector<vector<int>> ys;
vector<vector<int>> bit;
Fenwick2D(int _M): M(_M), ys(_M+1) {}
// register (value idx, position) for structure building
void fake_update(int v, int pos) {
for(int i = v; i <= M; i += i & -i) {
ys[i].push_back(pos);
}
}
// initialize internal BIT arrays after all fake_update calls
void init() {
bit.resize(M+1);
for(int i = 1; i <= M; i++) {
auto &v = ys[i];
sort(v.begin(), v.end());
v.erase(unique(v.begin(), v.end()), v.end());
bit[i].assign(v.size()+1, 0);
}
}
// point update: add delta at (value idx = v, position = pos)
void update(int v, int pos, int delta) {
for(int i = v; i <= M; i += i & -i) {
int idx = int(lower_bound(ys[i].begin(), ys[i].end(), pos) - ys[i].begin()) + 1;
for(int j = idx; j < (int)bit[i].size(); j += j & -j) {
bit[i][j] += delta;
}
}
}
// prefix sum for values <= v, positions <= pos
int query(int v, int pos) const {
int res = 0;
for(int i = v; i > 0; i -= i & -i) {
int idx = int(upper_bound(ys[i].begin(), ys[i].end(), pos) - ys[i].begin());
for(int j = idx; j > 0; j -= j & -j) {
res += bit[i][j];
}
}
return res;
}
// sum over values in [v_lo, v_hi], positions in [l, r]
int range_query(int v_lo, int v_hi, int l, int r) const {
if(v_lo > v_hi || l > r) return 0;
int a = query(v_hi, r) - query(v_hi, l - 1);
int b = query(v_lo - 1, r) - query(v_lo - 1, l - 1);
return a - b;
}
};
int main() {
ios::sync_with_stdio(false);
cin.tie(NULL);
int N, Q;
cin >> N >> Q;
vector<int> A(N+2);
for(int i = 1; i <= N; i++) cin >> A[i];
struct Query { int type, i, x, l, r; };
vector<Query> queries(Q);
// collect all values for compression and per-position possible values
vector<int> all_vals;
all_vals.reserve(N + Q + 5);
vector<vector<int>> pos_vals(N+2);
for(int i = 1; i <= N; i++) {
pos_vals[i].push_back(A[i]);
all_vals.push_back(A[i]);
}
for(int qi = 0; qi < Q; qi++) {
int t;
cin >> t;
queries[qi].type = t;
if(t == 1) {
cin >> queries[qi].i >> queries[qi].x;
all_vals.push_back(queries[qi].x);
pos_vals[queries[qi].i].push_back(queries[qi].x);
} else {
cin >> queries[qi].l >> queries[qi].r;
}
}
// compress all values
sort(all_vals.begin(), all_vals.end());
all_vals.erase(unique(all_vals.begin(), all_vals.end()), all_vals.end());
int M = all_vals.size();
auto comp = [&](int x) {
return int(lower_bound(all_vals.begin(), all_vals.end(), x) - all_vals.begin()) + 1;
};
// build Fenwick2D structure
Fenwick2D fw(M);
// fake updates for element events
for(int i = 1; i <= N; i++) {
auto &pv = pos_vals[i];
sort(pv.begin(), pv.end());
pv.erase(unique(pv.begin(), pv.end()), pv.end());
for(int v : pv) {
fw.fake_update(comp(v), i);
}
}
// fake updates for pair events (i, i+1)
for(int i = 1; i < N; i++) {
vector<int> uv = pos_vals[i];
uv.insert(uv.end(), pos_vals[i+1].begin(), pos_vals[i+1].end());
sort(uv.begin(), uv.end());
uv.erase(unique(uv.begin(), uv.end()), uv.end());
for(int v : uv) {
fw.fake_update(comp(v), i);
}
}
fw.init();
// initial population of weights
// element weight = +2
for(int i = 1; i <= N; i++) {
fw.update(comp(A[i]), i, +2);
}
// pair weight = +1
for(int i = 1; i < N; i++) {
int pv = max(A[i], A[i+1]);
fw.update(comp(pv), i, +1);
}
// process queries
for(auto &q : queries) {
if(q.type == 1) {
int idx = q.i;
int old = A[idx];
int neu = q.x;
// element update
fw.update(comp(old), idx, -2);
fw.update(comp(neu), idx, +2);
// pair (idx-1, idx)
if(idx > 1) {
int oldp = max(A[idx-1], old);
int newp = max(A[idx-1], neu);
fw.update(comp(oldp), idx-1, -1);
fw.update(comp(newp), idx-1, +1);
}
// pair (idx, idx+1)
if(idx < N) {
int oldp = max(old, A[idx+1]);
int newp = max(neu, A[idx+1]);
fw.update(comp(oldp), idx, -1);
fw.update(comp(newp), idx, +1);
}
A[idx] = neu;
} else {
int l = q.l, r = q.r;
int len = r - l + 1;
// total weight in [1..M] values, positions [l..r]
int total = fw.range_query(1, M, l, r);
// binary search on value-axis
int lo = 1, hi = M, ans_idx = 1;
while(lo <= hi) {
int mid = (lo + hi) >> 1;
int low = fw.range_query(1, mid-1, l, r);
int w = total - low;
if(w > len) {
ans_idx = mid;
lo = mid + 1;
} else {
hi = mid - 1;
}
}
cout << all_vals[ans_idx-2] << '\n';
}
}
return 0;
}