結果
| 問題 | No.2223 Merged Med | 
| コンテスト | |
| ユーザー |  | 
| 提出日時 | 2023-02-17 22:15:55 | 
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) | 
| 結果 | 
                                AC
                                 
                             | 
| 実行時間 | 1,100 ms / 7,000 ms | 
| コード長 | 3,489 bytes | 
| コンパイル時間 | 2,985 ms | 
| コンパイル使用メモリ | 213,284 KB | 
| 最終ジャッジ日時 | 2025-02-10 17:04:51 | 
| ジャッジサーバーID (参考情報) | judge2 / judge3 | 
(要ログイン)
| ファイルパターン | 結果 | 
|---|---|
| sample | AC * 3 | 
| other | AC * 33 | 
ソースコード
#include <bits/stdc++.h>
using i64 = long long;
template<class Info,
    class Merge = std::plus<Info>>
struct SegmentTree {
    const int n;
    const Merge merge;
    std::vector<Info> info;
    SegmentTree(int n) : n(n), merge(Merge()), info(4 << std::__lg(n)) {}
    SegmentTree(std::vector<Info> init) : SegmentTree(init.size()) {
        std::function<void(int, int, int)> build = [&](int p, int l, int r) {
            if (r - l == 1) {
                info[p] = init[l];
                return;
            }
            int m = (l + r) / 2;
            build(2 * p, l, m);
            build(2 * p + 1, m, r);
            pull(p);
        };
        build(1, 0, n);
    }
    void pull(int p) {
        info[p] = merge(info[2 * p], info[2 * p + 1]);
    }
    void modify(int p, int l, int r, int x, const Info &v) {
        if (r - l == 1) {
            info[p] = v;
            return;
        }
        int m = (l + r) / 2;
        if (x < m) {
            modify(2 * p, l, m, x, v);
        } else {
            modify(2 * p + 1, m, r, x, v);
        }
        pull(p);
    }
    void modify(int p, const Info &v) {
        modify(1, 0, n, p, v);
    }
    Info rangeQuery(int p, int l, int r, int x, int y) {
        if (l >= y || r <= x) {
            return Info();
        }
        if (l >= x && r <= y) {
            return info[p];
        }
        int m = (l + r) / 2;
        return merge(rangeQuery(2 * p, l, m, x, y), rangeQuery(2 * p + 1, m, r, x, y));
    }
    Info rangeQuery(int l, int r) {
        return rangeQuery(1, 0, n, l, r);
    }
};
constexpr int inf = 1E9;
struct Info {
    int sum;
    int min;
    int pre;
    int suf;
    Info() : sum{0}, min{inf}, pre{inf}, suf{inf} {};
    Info(int x) : sum{x}, min{std::min(x, 0)}, pre{min}, suf{min} {}
};
Info operator+(Info a, Info b) {
    Info c;
    c.sum = a.sum + b.sum;
    c.min = std::min({a.min, b.min, a.suf + b.pre});
    c.pre = std::min(a.pre, a.sum + b.pre);
    c.suf = std::min(a.suf + b.sum, b.suf);
    return c;
}
int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    
    int n, q;
    std::cin >> n >> q;
    
    std::vector<int> a(n);
    for (int i = 0; i < n; i++) {
        std::cin >> a[i];
    }
    
    std::vector<int> l(q), r(q), lo(q, 1), hi(q, n);
    for (int i = 0; i < q; i++) {
        std::cin >> l[i] >> r[i];
        l[i]--;
    }
    
    while (true) {
        bool ok = true;
        
        std::vector<std::pair<int, int>> events;
        for (int i = 0; i < q; i++) {
            if (lo[i] < hi[i]) {
                int x = (lo[i] + hi[i]) / 2;
                events.emplace_back(x, n + i);
                ok = false;
            }
        }
        
        if (ok) {
            break;
        }
        
        for (int i = 0; i < n; i++) {
            events.emplace_back(a[i], i);
        }
        
        SegmentTree<Info> seg(std::vector<Info>(n, -1));
        std::sort(events.begin(), events.end());
        
        for (auto [x, i] : events) {
            if (i < n) {
                seg.modify(i, 1);
            } else {
                i -= n;
                auto info = seg.rangeQuery(l[i], r[i]);
                if (info.sum - std::min(0, info.min + 1) > 0) {
                    hi[i] = x;
                } else {
                    lo[i] = x + 1;
                }
            }
        }
    }
    
    for (int i = 0; i < q; i++) {
        std::cout << lo[i] << "\n";
    }
    
    return 0;
}
            
            
            
        