結果

問題 No.3116 More and more teleporter
ユーザー AKI
提出日時 2025-04-20 13:17:13
言語 C++17
(gcc 13.3.0 + boost 1.87.0)
結果
AC  
実行時間 95 ms / 2,000 ms
コード長 2,048 bytes
コンパイル時間 2,074 ms
コンパイル使用メモリ 196,004 KB
実行使用メモリ 12,836 KB
最終ジャッジ日時 2025-04-20 13:17:18
合計ジャッジ時間 4,212 ms
ジャッジサーバーID
(参考情報)
judge2 / judge3
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
other AC * 22
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <bits/stdc++.h>
using namespace std;
using int64 = long long;
const int64 INF = (1LL<<60);

struct SegMin {
    int n;
    vector<int64> seg;
    SegMin(int N): n(1) {
        while (n < N) n <<= 1;
        seg.assign(2*n, INF);
    }
    // 現在値と比較して小さければ更新(min で保持)
    void chmin(int idx, int64 val) {
        idx += n;
        if (val >= seg[idx]) return;
        seg[idx] = val;
        for (idx >>= 1; idx; idx >>= 1)
            seg[idx] = min(seg[idx<<1], seg[idx<<1|1]);
    }
    // [l,r](0-index, 両端含む)の最小値
    int64 range_min(int l, int r) const {
        if (l > r) return INF;
        l += n;  r += n;
        int64 res = INF;
        while (l <= r) {
            if (l & 1) res = min(res, seg[l++]);
            if (!(r & 1)) res = min(res, seg[r--]);
            l >>= 1;  r >>= 1;
        }
        return res;
    }
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int N, Q;
    if (!(cin >> N >> Q)) return 0;
    
    SegMin leftSeg(N), rightSeg(N);
    vector<int64> bestCost(N, INF);   // マス毎の最安テレポートコスト
    
    while (Q--) {
        int type;
        cin >> type;
        if (type == 1) {
            int x; cin >> x;          // 1‑based
            --x;                      // 0‑basedに
            int64 ans = x;            // 歩くだけ ⇒ cost = x‑(0) = x
            int64 lm = leftSeg.range_min(0, x);
            if (lm < INF) ans = min(ans, lm + (int64)(x+1));   // +1 は元の 1‑based
            int64 rm = rightSeg.range_min(x, N-1);
            if (rm < INF) ans = min(ans, rm - (int64)(x+1));
            cout << ans << '\n';
        } else {
            int a; int64 c;
            cin >> a >> c;            // 1‑based
            --a;
            if (c < bestCost[a]) {
                bestCost[a] = c;
                leftSeg.chmin(a, c - (a+1));   // (c - a)
                rightSeg.chmin(a, c + (a+1));  // (c + a)
            }
        }
    }
    return 0;
}
0