結果
| 問題 |
No.3116 More and more teleporter
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2025-05-23 07:28:09 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 131 ms / 2,000 ms |
| コード長 | 1,860 bytes |
| コンパイル時間 | 3,330 ms |
| コンパイル使用メモリ | 198,952 KB |
| 実行使用メモリ | 14,172 KB |
| 最終ジャッジ日時 | 2025-05-23 07:28:15 |
| 合計ジャッジ時間 | 5,353 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 22 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll INF = (1LL<<60);
struct SegTree {
int n;
vector<ll> t;
SegTree(int _n): n(_n), t(4*n, INF) {}
void update(int v, int tl, int tr, int pos, ll val) {
if (tl == tr) {
t[v] = min(t[v], val);
return;
}
int tm = (tl + tr) >> 1;
if (pos <= tm) update(v<<1, tl, tm, pos, val);
else update(v<<1|1, tm+1, tr, pos, val);
t[v] = min(t[v<<1], t[v<<1|1]);
}
ll query(int v, int tl, int tr, int l, int r) {
if (l > r) return INF;
if (l <= tl && tr <= r) return t[v];
int tm = (tl + tr) >> 1;
ll res = INF;
if (l <= tm) res = min(res, query(v<<1, tl, tm, l, r));
if (r > tm) res = min(res, query(v<<1|1, tm+1, tr, l, r));
return res;
}
// ラッパー
void update(int pos, ll val) { update(1,1,n,pos,val); }
ll query(int l, int r) { return query(1,1,n,l,r); }
};
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int N, Q;
cin >> N >> Q;
SegTree leftTree(N), rightTree(N);
while (Q--) {
int type;
cin >> type;
if (type == 1) {
int x;
cin >> x;
ll ans = x - 1; // 純粋歩行
// 左サイドのワープルート
ll lm = leftTree.query(1, x);
if (lm < INF) ans = min(ans, lm + x);
// 右サイドのワープルート
ll rm = rightTree.query(x, N);
if (rm < INF) ans = min(ans, rm - x);
cout << ans << "\n";
}
else {
int x; ll c;
cin >> x >> c;
// テレポーター設置
leftTree.update(x, c - x);
rightTree.update(x, c + x);
}
}
return 0;
}