結果

問題 No.2988 Min-Plus Convolution Query
ユーザー 👑 NachiaNachia
提出日時 2024-12-13 00:59:48
言語 C++17
(gcc 12.3.0 + boost 1.83.0)
結果
WA  
実行時間 -
コード長 5,142 bytes
コンパイル時間 1,466 ms
コンパイル使用メモリ 101,516 KB
実行使用メモリ 106,728 KB
最終ジャッジ日時 2024-12-13 01:00:31
合計ジャッジ時間 31,823 ms
ジャッジサーバーID
(参考情報)
judge2 / judge4
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
6,816 KB
testcase_01 AC 2 ms
6,816 KB
testcase_02 WA -
testcase_03 AC 1,484 ms
105,960 KB
testcase_04 AC 1,466 ms
105,260 KB
testcase_05 AC 53 ms
14,076 KB
testcase_06 WA -
testcase_07 AC 2 ms
6,816 KB
testcase_08 AC 2 ms
6,816 KB
testcase_09 AC 106 ms
16,684 KB
testcase_10 AC 56 ms
10,904 KB
testcase_11 AC 12 ms
6,820 KB
testcase_12 WA -
testcase_13 WA -
testcase_14 WA -
testcase_15 WA -
testcase_16 WA -
testcase_17 WA -
testcase_18 WA -
testcase_19 WA -
testcase_20 AC 1,539 ms
106,072 KB
testcase_21 WA -
testcase_22 WA -
testcase_23 AC 1,489 ms
105,644 KB
testcase_24 AC 1,484 ms
105,260 KB
testcase_25 AC 1,250 ms
104,060 KB
testcase_26 AC 1,276 ms
104,596 KB
testcase_27 WA -
testcase_28 WA -
testcase_29 WA -
testcase_30 WA -
testcase_31 WA -
testcase_32 AC 2 ms
6,820 KB
testcase_33 AC 2 ms
6,816 KB
testcase_34 AC 2 ms
6,820 KB
testcase_35 AC 2 ms
6,820 KB
testcase_36 AC 2 ms
6,816 KB
testcase_37 AC 3 ms
6,816 KB
testcase_38 AC 2 ms
6,820 KB
testcase_39 AC 2 ms
6,816 KB
testcase_40 AC 2 ms
6,820 KB
testcase_41 AC 2 ms
6,816 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#ifdef NACHIA
#define _GLIBCXX_DEBUG
#else
#define NDEBUG
#endif
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using i64 = long long;
using u64 = unsigned long long;
#define rep(i,n) for(int i=0; i<int(n); i++)
const i64 INF = 1001001001001001001;
template<typename A> void chmin(A& l, const A& r){ if(r < l) l = r; }
template<typename A> void chmax(A& l, const A& r){ if(l < r) l = r; }
using namespace std;
#include <atcoder/modint>
using Modint = atcoder::static_modint<998244353>;

namespace nachia {

template<class Elem>
struct SmawkAlgorithm {

template<class Gen, class Cmp = std::less<Elem>>
static std::vector<std::pair<Elem, int>> Solve(
    int height, int width,
    Gen gen,
    Cmp cmp = Cmp()
){
    if(height == 0) return std::vector<std::pair<Elem, int>>(0);
    auto reduce = [&](int yst, const std::vector<int>& cols)
     -> std::vector<int> {
        int w = int(cols.size());
        std::vector<int> idx;
        int r = -1;
        for(int q=0; q<w; q++){
            if(idx.empty()){
                idx.push_back(q);
                r += yst;
                continue;
            }
            int a = cols[idx.back()];
            int b = cols[q];
            if(cmp(gen(r,a), gen(r,b))){
                if(r+yst < height){ idx.push_back(q); r += yst; }
            } else {
                idx.pop_back(); q--; r -= yst;
            }
        }
        return idx;
    };
    auto ysts = std::vector<int>(1,1);
    auto cols = std::vector<std::vector<int>>(1);
    for(int i=0; i<width; i++) cols[0].push_back(i);
    cols[0] = reduce(1, cols[0]);
    while(true){
        int nxst = ysts.back() * 2;
        if(height < nxst) break;
        auto nxc = reduce(nxst, cols.back());
        int w = nxc.size();
        for(int i=0; i<w; i++) nxc[i] = cols.back()[nxc[i]];
        cols.push_back(move(nxc));
        ysts.push_back(nxst);
    }
    std::vector<std::pair<Elem,int>> ans(height, std::make_pair(gen(0,0), 0));
    while(cols.size()){
        auto x = std::move(cols.back()); cols.pop_back();
        int st = ysts.back(); ysts.pop_back();
        int p = 0;
        for(int y=st-1; y<height; y+=st*2){
            int r = y+st < height ? ans[y+st].second : width-1;
            ans[y] = std::make_pair(gen(y,x[p]), x[p]);
            while(p+1 < int(x.size()) && x[p+1] <= r){
                int xp = x[++p];
                auto fxp = gen(y,xp);
                if(!cmp(ans[y].first, fxp)) ans[y] = std::make_pair(fxp, xp);
            }
        }
    }
    return ans;
}

};


// bool Func(y, xl, xr) , xl < xr
//   returns if A[y][xl] < A[y][xr]
template<class Func>
std::vector<int> SmawkAlgorithmIndependent(
    int height, int width,
    Func f
){
    auto tmp = SmawkAlgorithm<std::pair<int,int>>::Solve(
        height, width,
        [](int r, int c){ return std::make_pair(r,c); },
        [&f](std::pair<int,int> l, std::pair<int,int> r) -> bool {
            return f(l.first, l.second, r.second); } );
    std::vector<int> res(height);
    for(int i=0; i<height; i++) res[i] = tmp[i].first;
    return res;
}

} // namespace nachia

void testcase(){
    i64 N, Q; cin >> N >> Q;
    vector<i64> A(N); rep(i,N) cin >> A[i];
    vector<int> AlastChange(N, 0);
    vector<i64> B(N*3, INF); rep(i,N) cin >> B[N+i];
    vector<i64> ans(Q, INF);
    vector<i64> buf(N*2, INF);
    vector<int> K(Q);
    auto sub = [&](int ql, int qr, const vector<int>& J){
        if(J.empty()) return;
        vector<int> V;
        int v_min = J.front();
        int v_max = N - 1 + J.back();
        for(int i=ql; i<qr; i++) if(v_min <= K[i] && K[i] <= v_max) V.push_back(K[i]);
        if(V.empty()) return;
        sort(V.begin(), V.end());
        int n = V.size();
        int m = J.size();
        auto q = nachia::SmawkAlgorithm<i64>().Solve(
            n, m,
            [&](int yz, int xz) -> i64 { return B[V[yz]-J[xz]+N] + A[J[xz]]; } );
        rep(i,n) buf[V[i]] = q[i].first;
        for(int i=ql; i<qr; i++) if(v_min <= K[i] && K[i] <= v_max) chmin(ans[i], buf[K[i]]);
    };
    int Q2 = 1; while(Q2<Q) Q2*=2;
    vector<vector<pair<i64,int>>> query(Q2*2);
    auto qadd = [&](int l, int r, int p, i64 x) -> void {
        l += Q2; r += Q2;
        while(l < r){
            if(l % 2 == 1) query[l++].push_back({ p, x });
            if(r % 2 == 1) query[--r].push_back({ p, x });
            l /= 2; r /= 2;
        }
    };
    rep(qi,Q){
        int p; cin >> p; p--;
        i64 x; cin >> x;
        int k; cin >> k; K[qi] = k - 2;
        qadd(AlastChange[p], qi, p, A[p]);
        AlastChange[p] = qi;
        A[p] = x;
    }
    rep(i,N) qadd(AlastChange[i], Q, i, A[i]);
    rep(i,N) A[i] = INF;
    for(int d=1; d<=Q2; d*=2){
        int st = Q2 / d;
        for(int l=0; l<d; l++){
            if(Q < st * (l+1)) continue;
            vector<int> J;
            for(auto [u,v] : query[d+l]){ A[u] = v; J.push_back(u); }
            sort(J.begin(), J.end());
            sub(st * l, st * (l+1), J);
        }
    }
    rep(i,Q) cout << ans[i] << '\n';
}

int main(){
    ios::sync_with_stdio(false); cin.tie(nullptr);
    testcase();
    return 0;
}
0