結果
問題 |
No.952 危険な火薬庫
|
ユーザー |
![]() |
提出日時 | 2025-09-03 03:52:42 |
言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 983 ms / 2,000 ms |
コード長 | 2,543 bytes |
コンパイル時間 | 3,335 ms |
コンパイル使用メモリ | 285,144 KB |
実行使用メモリ | 7,716 KB |
最終ジャッジ日時 | 2025-09-03 03:52:56 |
合計ジャッジ時間 | 13,097 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 23 |
ソースコード
#include <bits/stdc++.h> using namespace std; using ll = long long; using pll = pair<ll, ll>; #define vc vector using vl = vc<ll>; #define ov(a, b, c, name, ...) name #define rep2(i, l, r) for(ll i = (l); i < ll(r); i++) #define rep1(i, n) rep2(i, 0, n) #define rep(...) ov(__VA_ARGS__, rep2, rep1)(__VA_ARGS__) #define fec(...) for(const auto& __VA_ARGS__) #define per(i, a, b) for(ll i = ll(a) - 1; i >= ll(b); i--) #define ALL(x) begin(x), end(x) #define SZ(x) (ll) size(x) #define LB(v, x) (lower_bound(ALL(v), x) - begin(v)) #define eb emplace_back bool chmin(auto& a, auto b) { return a > b ? a = b, 1 : 0; } bool chmax(auto& a, auto b) { return a < b ? a = b, 1 : 0; } const ll INF = ll(4e18) + 100; void printvec(const auto& v) { for(auto it = begin(v); it != end(v); it++) cout << *it << " "; cout << endl; } #ifdef LOCAL #define local(...) __VA_ARGS__ #else #define local(...) #endif // monotone 行列の各行について、最小値を取る場所とその値を返す template<typename T> vc<pair<int, T>> monotone_minima(int h, int w, auto f) { vc<pair<int, T>> dp(h, pair(-1, T())); auto rec = [&](auto&& rec, int u, int d, int l, int r) { if(u > d) return; int mid = (u + d) >> 1; auto& [idx, mi] = dp[mid]; idx = l, mi = f(mid, l); rep(i, l + 1, r + 1) if(chmin(mi, f(mid, i))) idx = i; rec(rec, u, mid - 1, l, idx); rec(rec, mid + 1, d, idx, r); }; rec(rec, 0, h - 1, 0, w - 1); return dp; } // 辺コストが monge である N 頂点 DAG の d 辺最短路を d=1,...,N について vl monge_d_edge_enum(int N, auto f) { const ll INFL = 2 * INF + 100; vl ans(N + 1, INF), dp(N + 1, INFL); dp[0] = 0; rep(d, 1, N + 1) { auto mi = monotone_minima<ll>(N + 1, N + 1, [&](int j, int i) { return i < j ? dp[i] + f(i, j) : INFL; }); per(i, N + 1, d) dp[i] = dp[mi[i].first] + f(mi[i].first, i); ans[d] = dp[N]; } return ans; } int main() { cin.tie(0)->sync_with_stdio(0); ll N; cin >> N; vl A(N); rep(i, N) cin >> A.at(i); ll s = 0, l = 0, r = 0; auto add = [&](ll i) { s += A.at(i); }; auto del = [&](ll i) { s -= A.at(i); }; auto f = [&](ll L, ll R) -> ll { while(L < l) add(--l); while(r < R) add(r++); while(l < L) del(l++); while(R < r) del(--r); return s; }; auto g = [&](ll i, ll j) -> ll { ll tmp = f(i, j - 1); return tmp * tmp; }; auto ans = monge_d_edge_enum(N + 1, g); rep(k, 1, N + 1) cout << ans.at(N + 1 - k) << "\n"; }