結果

問題 No.3122 Median of Medians of Division
ユーザー karashi-0086A2
提出日時 2025-04-20 19:44:51
言語 C++17
(gcc 13.3.0 + boost 1.87.0)
結果
MLE  
実行時間 -
コード長 2,507 bytes
コンパイル時間 2,587 ms
コンパイル使用メモリ 207,972 KB
実行使用メモリ 822,732 KB
最終ジャッジ日時 2025-04-20 19:45:05
合計ジャッジ時間 11,842 ms
ジャッジサーバーID
(参考情報)
judge4 / judge1
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample -- * 1
other MLE * 1 -- * 39
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <bits/stdc++.h>
using namespace std;

const int MAXN = 200005;
vector<int> A, comp;

struct Node {
    Node *left, *right;
    int count;
    Node() : left(nullptr), right(nullptr), count(0) {}
};

Node* build(int l, int r) {
    Node* node = new Node();
    if (l == r) return node;
    int m = (l + r) / 2;
    node->left = build(l, m);
    node->right = build(m + 1, r);
    return node;
}

Node* update(Node* pre, int l, int r, int pos) {
    Node* node = new Node(*pre);
    node->count++;
    if (l == r) return node;
    int m = (l + r) / 2;
    if (pos <= m) node->left = update(pre->left, l, m, pos);
    else node->right = update(pre->right, m + 1, r, pos);
    return node;
}

int query(Node* u, Node* v, int l, int r, int k) {
    if (l == r) return l;
    int cnt = v->left->count - u->left->count;
    int m = (l + r) / 2;
    if (cnt >= k) return query(u->left, v->left, l, m, k);
    else return query(u->right, v->right, m + 1, r, k - cnt);
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int N, Q;
    cin >> N >> Q;
    A.resize(N);
    vector<tuple<int, int, int>> queries;

    for (int i = 0; i < N; i++) {
        cin >> A[i];
        comp.push_back(A[i]);
    }

    for (int i = 0; i < Q; i++) {
        int type, a, b;
        cin >> type >> a >> b;
        queries.emplace_back(type, a, b);
        if (type == 1) comp.push_back(b);
    }

    // 座標圧縮
    sort(comp.begin(), comp.end());
    comp.erase(unique(comp.begin(), comp.end()), comp.end());

    auto get_id = [&](int x) {
        return lower_bound(comp.begin(), comp.end(), x) - comp.begin();
    };

    for (int i = 0; i < N; i++) A[i] = get_id(A[i]);

    vector<Node*> roots(N + 1);
    roots[0] = build(0, comp.size() - 1);
    for (int i = 0; i < N; i++) {
        roots[i + 1] = update(roots[i], 0, comp.size() - 1, A[i]);
    }

    for (auto [type, a, b] : queries) {
        if (type == 1) {
            // 更新
            int id = a - 1;
            int new_val = get_id(b);
            A[id] = new_val;
            roots[id + 1] = update(roots[id], 0, comp.size() - 1, new_val);
            for (int i = id + 1; i < N; i++) {
                roots[i + 1] = update(roots[i], 0, comp.size() - 1, A[i]);
            }
        } else {
            int l = a - 1, r = b;
            int len = r - l;
            int k = (len + 1) / 2;
            int ans = query(roots[l], roots[r], 0, comp.size() - 1, k);
            cout << comp[ans] << '\n';
        }
    }
}
0