結果
| 問題 |
No.2859 Falling Balls
|
| コンテスト | |
| ユーザー |
nonon
|
| 提出日時 | 2025-01-30 17:57:33 |
| 言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 197 ms / 3,000 ms |
| コード長 | 3,560 bytes |
| コンパイル時間 | 4,252 ms |
| コンパイル使用メモリ | 291,196 KB |
| 実行使用メモリ | 23,816 KB |
| 最終ジャッジ日時 | 2025-01-30 17:57:45 |
| 合計ジャッジ時間 | 11,007 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 30 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
template <typename Monoid>
struct segtree {
using S = typename Monoid::S;
segtree() : segtree(0) {}
segtree(int _n) : segtree(vector<S>(_n, Monoid::e())) {}
segtree(const vector<S> &v) : n(v.size()) {
log = 1;
while ((1 << log) < n) log++;
sz = 1 << log;
d = vector<S>(2 * sz, Monoid::e());
for (int i = 0; i < n; i++) d[i + sz] = v[i];
for (int i = sz - 1; i >= 1; i--) update(i);
}
void set(int p, const S &x) {
assert(0 <= p && p < n);
p += sz;
d[p] = x;
for (int i = 1; i <= log; i++) update(p >> i);
}
S get(int p) const {
assert(0 <= p && p < n);
return d[p + sz];
}
S prod(int l, int r) const {
assert(0 <= l && l <= r && r <= n);
l += sz;
r += sz;
S pl = Monoid::e(), pr = Monoid::e();
while (l < r) {
if (l & 1) pl = Monoid::op(pl, d[l++]);
if (r & 1) pr = Monoid::op(d[--r], pr);
l >>= 1;
r >>= 1;
}
return Monoid::op(pl, pr);
}
S all_prod() const { return d[1]; }
private:
int n, log, sz;
vector<S> d;
void update(int p) {
d[p] = Monoid::op(d[2 * p], d[2 * p + 1]);
}
};
template<typename Monoid, typename T = int>
struct triangular_transition {
using S = typename Monoid::S;
triangular_transition(int _n = 0) : n(_n) {
ts.reserve(n);
xs.reserve(n);
}
void add_point(T t, T x) {
ts.emplace_back(t);
xs.emplace_back(x);
}
template<typename L>
vector<S> run(const L &f, bool variable_start = false) {
if (variable_start) {
T x_max = 0;
for (auto x : xs) x_max = max(x_max, abs(x));
for (auto &t : ts) t += x_max;
}
n = ts.size();
vector<T> us(n), vs(n);
vector<int> ord(n);
for (int i = 0; i < n; i++) {
us[i] = ts[i] - xs[i];
vs[i] = ts[i] + xs[i];
ord[i] = i;
}
sort(ord.begin(), ord.end(), [&](int i, int j) {
return us[i] == us[j] ? vs[i] < vs[j] : us[i] < us[j];
});
vector<T> b = vs;
sort(b.begin(), b.end());
b.erase(unique(b.begin(), b.end()), b.end());
vector<S> dp(n, Monoid::e());
segtree<Monoid> seg(b.size() + 1);
seg.set(0, f(-1, Monoid::e()));
for (int i : ord) {
T u = us[i], v = vs[i];
if (u < 0 || v < 0) continue;
int j = lower_bound(b.begin(), b.end(), v) - b.begin();
dp[i] = f(i, seg.prod(0, j + 1));
seg.set(j, dp[i]);
}
return dp;
}
private:
int n;
vector<T> ts, xs;
};
struct Monoid {
using S = long long;
static S op(S a, S b) {
return max(a, b);
}
static S e() {
return -1LL << 60;
}
};
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int N, K;
cin >> N >> K;
vector<long long> T(N), X(N), C(N);
for (int i = 0; i < N; i++) cin >> T[i];
for (int i = 0; i < N; i++) cin >> X[i];
for (int i = 0; i < N; i++) cin >> C[i];
triangular_transition<Monoid, long long> DP;
for (int i = 0; i < N; i++) {
T[i] *= K;
DP.add_point(T[i], X[i]);
}
auto f = [&](int i, long long c) -> long long {
if (i == -1) return 0;
return c + C[i];
};
auto ans = DP.run(f);
cout << *max_element(ans.begin(), ans.end()) << endl;
}
nonon