結果

問題 No.2988 Min-Plus Convolution Query
ユーザー tatyamtatyam
提出日時 2024-11-27 02:46:57
言語 C++23
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 653 ms / 2,000 ms
コード長 3,182 bytes
コンパイル時間 1,718 ms
コンパイル使用メモリ 129,808 KB
実行使用メモリ 270,096 KB
最終ジャッジ日時 2024-12-12 23:30:44
合計ジャッジ時間 17,705 ms
ジャッジサーバーID
(参考情報)
judge2 / judge5
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
6,820 KB
testcase_01 AC 2 ms
6,820 KB
testcase_02 AC 627 ms
259,876 KB
testcase_03 AC 614 ms
266,128 KB
testcase_04 AC 615 ms
266,940 KB
testcase_05 AC 43 ms
19,224 KB
testcase_06 AC 2 ms
6,816 KB
testcase_07 AC 2 ms
6,816 KB
testcase_08 AC 2 ms
6,820 KB
testcase_09 AC 115 ms
85,568 KB
testcase_10 AC 33 ms
23,584 KB
testcase_11 AC 9 ms
6,816 KB
testcase_12 AC 27 ms
19,148 KB
testcase_13 AC 228 ms
118,096 KB
testcase_14 AC 34 ms
22,616 KB
testcase_15 AC 377 ms
194,720 KB
testcase_16 AC 557 ms
257,240 KB
testcase_17 AC 329 ms
184,192 KB
testcase_18 AC 321 ms
182,276 KB
testcase_19 AC 293 ms
174,716 KB
testcase_20 AC 629 ms
267,916 KB
testcase_21 AC 623 ms
268,044 KB
testcase_22 AC 612 ms
267,916 KB
testcase_23 AC 635 ms
269,960 KB
testcase_24 AC 645 ms
270,096 KB
testcase_25 AC 556 ms
267,916 KB
testcase_26 AC 544 ms
267,788 KB
testcase_27 AC 629 ms
268,048 KB
testcase_28 AC 653 ms
267,788 KB
testcase_29 AC 635 ms
269,964 KB
testcase_30 AC 631 ms
267,912 KB
testcase_31 AC 626 ms
267,912 KB
testcase_32 AC 2 ms
6,816 KB
testcase_33 AC 2 ms
6,816 KB
testcase_34 AC 2 ms
6,816 KB
testcase_35 AC 2 ms
6,820 KB
testcase_36 AC 2 ms
6,820 KB
testcase_37 AC 2 ms
6,820 KB
testcase_38 AC 2 ms
6,816 KB
testcase_39 AC 2 ms
6,816 KB
testcase_40 AC 2 ms
6,820 KB
testcase_41 AC 2 ms
6,820 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

// 時間軸をセグ木状に分割統治 + monotone minima
#include <algorithm>
#include <array>
#include <cassert>
#include <climits>
#include <cstdlib>
#include <iostream>
#include <vector>
using namespace std;
using ll = long long;
const ll INF = LLONG_MAX / 4;
using P = pair<int, int>;
bool chmin(ll& a, ll b) { return a > b ? a = b, 1 : 0; }

char* buf;
ll buf_ind;
template<class T> struct small {
    typedef T value_type;
    small() {}
    template<class U> small(const U&) {}
    T* allocate(size_t n) {
        if (n & 7) {
            n &= -8;
            n += 8;
        }
        buf_ind -= n * sizeof(T);
        buf_ind &= 0 - alignof(T);
        assert(buf_ind >= 0);
        return (T*)(buf + buf_ind);
    }
    void deallocate(T*, size_t) {}
};
using V = vector<P, small<P>>;

int main() {
    buf_ind = 3 << 28;
    buf = (char*)malloc(buf_ind);
    cin.tie(0)->sync_with_stdio(0);

    ll N, Q;
    cin >> N >> Q;
    vector<ll> A(N), B(N);
    for (ll& x : A) cin >> x;
    for (ll& x : B) cin >> x;
    vector<array<ll, 3>> queries(Q);
    for (auto& [p, x, k] : queries) {
        cin >> p >> x >> k;
        p--;
        k -= 2;
    }

    // {L, R, i, a}
    vector<array<ll, 4>> A_range;
    {
        vector<ll> L(N);
        for (ll t = 0; t < Q; t++) {
            auto [p, x, k] = queries[t];
            A_range.push_back({L[p], t, p, A[p]});
            L[p] = t;
            A[p] = x;
        }
        for (ll i = 0; i < N; i++) A_range.push_back({L[i], Q, i, A[i]});
    }
    ranges::sort(A_range, {}, [](auto& x) { return x[2]; });
    vector<P> k_query;  // {k, t}
    for (ll t = 0; t < Q; t++) {
        auto [p, x, k] = queries[t];
        k_query.push_back({k, t});
    }
    ranges::sort(k_query);

    vector<V> A_seg(Q * 2), C_seg(Q * 2);
    for (auto [L, R, i, a] : A_range) {
        L += Q;
        R += Q;
        for (; L < R; L >>= 1, R >>= 1) {
            if (L & 1) A_seg[L++].push_back({i, a});
            if (R & 1) A_seg[--R].push_back({i, a});
        }
    }
    for (auto [k, t] : k_query) {
        ll i = t + Q;
        do C_seg[i].push_back({k, t});
        while (i >>= 1);
    }

    vector<ll> ans(Q, INF);
    auto solve = [&](const V& A, const V& C) {
        auto minima = [&](auto minima, ll x1, ll x2, ll y1, ll y2) {
            if (x1 > x2) return;
            const ll x3 = (x1 + x2) / 2;
            auto [k, t] = C[x3];
            ll y3 = -1, mn = INF * 2;
            for (ll y = y1; y <= y2; y++) {
                auto [i, a] = A[y];
                const ll j = k - i;
                if (chmin(mn, [&] {
                        if (j < 0) return INF - j;
                        if (j >= N) return INF + j;
                        return a + B[j];
                    }())) y3 = y;
            }
            assert(y3 != -1);
            chmin(ans[t], mn);
            minima(minima, x1, x3 - 1, y1, y3);
            minima(minima, x3 + 1, x2, y3, y2);
        };
        if (A.empty() || C.empty()) return;
        minima(minima, 0, size(C) - 1, 0, size(A) - 1);
    };

    for (ll i = 1; i < Q * 2; i++) {
        solve(A_seg[i], C_seg[i]);
    }

    for (ll x : ans) cout << x << '\n';
}
0