結果
| 問題 | No.1297 銅像 |
| コンテスト | |
| ユーザー |
👑 tatyam
|
| 提出日時 | 2020-09-12 20:01:05 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 209 ms / 2,000 ms |
| コード長 | 2,359 bytes |
| コンパイル時間 | 2,528 ms |
| コンパイル使用メモリ | 207,428 KB |
| 最終ジャッジ日時 | 2025-01-14 13:42:56 |
|
ジャッジサーバーID (参考情報) |
judge3 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 21 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
using ll = int64_t;
using pll = pair<ll, ll>;
const ll LINF = 0x1fffffffffffffff;
template< typename T >
struct LiChaoTree {
struct Line {
T a, b;
Line(T a, T b) : a(a), b(b) {}
inline T get(T x) const { return a * x + b; }
inline bool over(const Line &b, const T &x) const {
return get(x) < b.get(x);
}
};
vector< T > xs;
vector< Line > seg;
int sz;
LiChaoTree(const vector< T > &x, T INF) : xs(x) {
sz = 1;
while(sz < xs.size()) sz <<= 1;
while(xs.size() < sz) xs.push_back(xs.back() + 1);
seg.assign(2 * sz - 1, Line(0, INF));
}
void update(Line &x, int k, int l, int r) {
int mid = (l + r) >> 1;
auto latte = x.over(seg[k], xs[l]), malta = x.over(seg[k], xs[mid]);
if(malta) swap(seg[k], x);
if(l + 1 >= r) return;
else if(latte != malta) update(x, 2 * k + 1, l, mid);
else update(x, 2 * k + 2, mid, r);
}
void update(T a, T b) { // ax+b
Line l(a, b);
update(l, 0, 0, sz);
}
T query(T x) { // xs[k]
int k = lower_bound(xs.begin(), xs.end(), x) - xs.begin();
k += sz - 1;
T ret = seg[k].get(x);
while(k > 0) {
k = (k - 1) >> 1;
ret = min(ret, seg[k].get(x));
}
return ret;
}
};
signed main(){
ll n, C;
cin >> n >> C;
vector<pll> a(n);
for(pll& i : a) cin >> i.first >> i.second;
vector<ll> dp1(n+1);
vector<ll> dp2(n+1);
dp1[0] = LINF;
vector<ll> x1(n), x2(n);
for(ll i = 0; i < n; i++){
x1[i] = a[i].first + C * (i + 1);
x2[i] = i + 1;
}
sort(x1.begin(), x1.end());
x1.erase(unique(x1.begin(), x1.end()), x1.end());
LiChaoTree<ll> cht1(x1, LINF), cht2(x2, LINF);
for(ll i = 0; i < n; i++){
const auto [A, B] = a[i];
cht1.update(-i, dp2[i] + C * i * (i + 1) / 2);
dp1[i + 1] = cht1.query(A + C * (i + 1)) + A * (i + 1) + B + C * i * (i + 1) / 2;
if(i){
cht2.update(a[i - 1].first - C * i, dp1[i] - a[i - 1].first * i + C * i * (i - 1) / 2);
dp2[i + 1] = min(dp1[i + 1], cht2.query(i + 1) + C * (i + 1) * (i + 2) / 2);
}
else dp2[i + 1] = dp1[i + 1];
}
cout << dp2[n] << endl;
}
tatyam