結果
問題 |
No.952 危険な火薬庫
|
ユーザー |
![]() |
提出日時 | 2025-05-15 12:46:07 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
TLE
|
実行時間 | - |
コード長 | 5,445 bytes |
コンパイル時間 | 2,944 ms |
コンパイル使用メモリ | 214,996 KB |
実行使用メモリ | 7,844 KB |
最終ジャッジ日時 | 2025-05-15 12:46:16 |
合計ジャッジ時間 | 7,892 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | TLE * 1 -- * 22 |
ソースコード
#include <bits/stdc++.h> using namespace std; template<class S, class T> inline bool chmax(S &a, T b) { return (a < b ? a = b, 1 : 0); } template<class S, class T> inline bool chmin(S &a, T b) { return (a > b ? a = b, 1 : 0); } using pint = pair<int, int>; using pll = pair<long long, long long>; using tint = array<int, 3>; using tll = array<long long, 3>; using fint = array<int, 4>; using fll = array<long long, 4>; using vint = vector<int>; using vll = vector<long long>; using ll = long long; using u32 = unsigned int; using u64 = unsigned long long; using int128 = __int128; using u128 = unsigned __int128; template <class T> using min_priority_queue = priority_queue<T, vector<T>, greater<T>>; #define REP(i, a) for (long long i = 0; i < (long long)(a); i++) #define REP2(i, a, b) for (long long i = a; i < (long long)(b); i++) #define RREP(i, a) for (long long i = (a)-1; i >= (long long)(0); --i) #define RREP2(i, a, b) for (long long i = (b)-1; i >= (long long)(a); --i) #define EB emplace_back #define PB push_back #define MP make_pair #define MT make_tuple #define FI first #define SE second #define ALL(x) x.begin(), x.end() #define COUT(x) cout << #x << " = " << (x) << " (L" << __LINE__ << ")" << endl // debug stream template<class T1, class T2> ostream& operator << (ostream &s, pair<T1,T2> P) { return s << '<' << P.first << ", " << P.second << '>'; } template<class T> ostream& operator << (ostream &s, vector<T> P) { for (int i = 0; i < P.size(); ++i) { if (i > 0) { s << " "; } s << P[i]; } return s; } template<class T> ostream& operator << (ostream &s, deque<T> P) { for (int i = 0; i < P.size(); ++i) { if (i > 0) { s << " "; } s << P[i]; } return s; } template<class T> ostream& operator << (ostream &s, vector<vector<T> > P) { for (int i = 0; i < P.size(); ++i) { s << endl << P[i]; } return s << endl; } template<class T> ostream& operator << (ostream &s, set<T> P) { for (auto it : P) { s << "<" << it << "> "; } return s; } template<class T> ostream& operator << (ostream &s, multiset<T> P) { for (auto it : P) { s << "<" << it << "> "; } return s; } template<class T1, class T2> ostream& operator << (ostream &s, map<T1,T2> P) { for (auto it : P) { s << "<" << it.first << "->" << it.second << "> "; } return s; } // Convex Hull Trick /* Func:Monge 性を仮定 - MIN: クエリ x の取りうる最小値 - MAX: クエリ x の取りうる最大値 (f_i(MAX) がオーバーフローしないように注意) - INF: 最大値 - insert (Func f_i): add f_i, O(log N) - query (x): min_i{ f_i(x) }, O(log N) */ template<class T> struct CHT { using Func = function<T(T)>; struct Node { Func func; Node *left, *right; Node(const Func& f) : left(nullptr), right(nullptr) { func = f; } }; const T MIN, MAX, INF; Node* root; CHT(T MIN, T MAX, T INF) : MIN(MIN), MAX(MAX), INF(INF), root(nullptr) { } Node* insert(Node* p, T low, T high, Func& f) { if (!p) return new Node(f); if (p->func(low) <= f(low) && p->func(high) <= f(high)) return p; if (p->func(low) >= f(low) && p->func(high) >= f(high)) { p->func = f; return p; } T mid = (low + high) / 2; if (p->func(mid) > f(mid)) swap(p->func, f); if (p->func(low) >= f(low)) p->left = insert(p->left, low, mid, f); else p->right = insert(p->right, mid, high, f); return p; } void insert(Func f) { root = insert(root, MIN, MAX, f); } T query(Node* p, T low, T high, T x) { if (!p) return INF; if (low == high) return p->func(x); T mid = (low + high) / 2; if (x <= mid) return min(p->func(x), query(p->left, low, mid, x)); else return min(p->func(x), query(p->right, mid, high, x)); } T query(T x) { return query(root, MIN, MAX, x); } }; int main() { int N; cin >> N; vector<ll> A(N), S(N+1, 0); REP(i, N) { cin >> A[i]; S[i+1] = S[i] + A[i]; } ll MAX = 1LL<<30, INF = 1LL<<60; vector<CHT<ll>> chts(N+1, CHT<ll>(0, MAX, INF)); vector dp(N+1, vector(N+1, vector(2, INF))); // 0: 白で終わる, 1: 黒で終わる vector mdp(N+2, vector(N+1, INF)); auto push = [&](int i, int j) -> void { auto func = [i, j, &S, &dp](ll x) -> ll { return dp[i][j][0] + (x - S[i]) * (x - S[i]); }; if (dp[i][j][0] < INF / 2) chts[i-j].insert(func); chmin(mdp[i+1][j], min(mdp[i][j], dp[i][j][1])); }; dp[0][0][0] = 0, dp[0][0][1] = 0; push(0, 0); REP2(i, 1, N+1) { REP(j, i+1) { // 0 -> 1 // REP2(k, 0, j) { // chmin(dp[i][j][1], dp[i-j+k][k][0] + (S[i] - S[i-j+k]) * (S[i] - S[i-j+k])); // } // dp[i-j][0][0] + (S[i]-S[i-j])^2 // dp[i-j+1][1][0] + (S[i]-S[i-j+1])^2 // ... // dp[i-1][j-1][0] + (S[i]-S[i-1])^2 chmin(dp[i][j][1], chts[i-j].query(S[i])); // 1 -> 0 // REP(k, i) { // chmin(dp[i][j][0], dp[k][j][1]); // } chmin(dp[i][j][0], mdp[i][j]); //cout << i << ", " << j << ": " << make_pair(dp[i][j][0], dp[i][j][1]) << endl; push(i, j); } } REP2(k, 1, N+1) { cout << min(dp[N][k][0], dp[N][k][1]) << endl; } }