結果
問題 | No.2859 Falling Balls |
ユーザー |
![]() |
提出日時 | 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; }