제출 #1320141

#제출 시각아이디문제언어결과실행 시간메모리
1320141fateless수열 (APIO14_sequence)C++20
50 / 100
23 ms12616 KiB
// #pragma GCC optimize("Ofast,unroll-loops") #include <bits/stdc++.h> using namespace std; #define now chrono::steady_clock::now().time_since_epoch().count() #define speedup cin.tie(0)->sync_with_stdio(0) #define bitcount(x) __builtin_popcountll(x) #define lla(x) x.rbegin(), x.rend() #define all(x) x.begin(), x.end() #define Tp template <class T> #define int long long #define pb push_back #define vc vector #define arr array const int inf = 1e18, N = 1e3 + 10, K = 250; Tp bool chmin (T &a, T b) {if (a > b) {a = b; return 1;} return 0;} Tp bool chmax (T &a, T b) {if (a < b) {a = b; return 1;} return 0;} struct line { int m, b, id; line (int _m = 0, int _b = 0, int _id = 0) : m(_m), b(_b), id(_id) {} int get (int x) {return (m * x + b);} }; struct segtree { struct node { line m; node *l, *r; node (line _m) : m(_m), l(NULL), r(NULL) {} }; int lb, rb; node* root; segtree (int _lb, int _rb) : lb(_lb), rb(_rb), root(NULL) {} void add (node *&x, line nw, int lx, int rx) { if (!x) {x = new node(nw); return;} int mid = (lx + rx) >> 1; bool l = nw.get(lx) > x->m.get(lx); bool m = nw.get(mid) > x->m.get(mid); if (m) swap(nw, x->m); if (rx - lx == 1) return; (l != m)? add (x->l, nw, lx, mid) : add (x->r, nw, mid, rx); } void add (line nw) {add(root, nw, lb, rb);} pair<int, int> get (node *x, int lx, int rx, int id) { if (!x) return {-inf, 0}; pair<int, int> res = {x->m.get(id), x->m.id}; if (rx - lx == 1) return res; int mid = (lx + rx) >> 1; if (id < mid) return max (res, get (x->l, lx, mid, id)); else return max (res, get (x->r, mid, rx, id)); } pair<int, int> get (int id) {return get(root, lb, rb, id);} }; static int a[N], pf[N], dp[K][N], opt[K][N]; inline void solve () { int n, kx; cin >> n >> kx; pf[0] = a[0] = 0; for (int i = 1; i <= n; i++) cin >> a[i]; for (int i = 1; i <= n; i++) pf[i] = pf[i - 1] + a[i]; memset(dp, -1, sizeof(dp)); memset(opt, 0, sizeof(opt)); for (int i = 1; i <= n; i++) dp[0][i] = 0; for (int i = 1; i <= kx; i++) { segtree st (0, pf[n] + 100); // cout << i << " :\n"; st.add(line(pf[i], dp[i - 1][i] - (pf[i] * pf[i]), i)); for (int j = i + 1; j <= n; j++) { auto [val, id] = st.get(pf[j]); tie(dp[i][j], opt[i][j]) = {val, id}; // cout << dp[i][j] << ' ' << opt[i][j] << '\n'; st.add(line(pf[j], dp[i - 1][j] - (pf[j] * pf[j]), j)); } // cout << "\n"; } int x = n; vc<int> ans; for (int i = kx; i >= 1; i--) { x = opt[i][x]; ans.pb(x); } reverse(all(ans)); cout << dp[kx][n] << '\n'; for (int &x : ans) cout << x << ' '; } signed main() { speedup; solve(); return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...