제출 #885239

#제출 시각아이디문제언어결과실행 시간메모리
885239quanlt206수열 (APIO14_sequence)C++17
100 / 100
607 ms89232 KiB
#include<bits/stdc++.h> #define X first #define Y second #define all(x) begin(x), end(x) #define FOR(i, a, b) for(int i = (a); i <= (b); i++) #define FORD(i, b, a) for(int i = (b); i >= (a); i--) #define REP(i, a, b) for (int i = (a); i < (b); i++) #define mxx max_element #define mnn min_element #define SQR(x) (1LL * (x) * (x)) #define MASK(i) (1LL << (i)) #define Point Vector #define left Left #define right Right #define div Div using namespace std; typedef long long ll; typedef unsigned long long ull; typedef double db; typedef long double ld; typedef pair<db, db> pdb; typedef pair<ld, ld> pld; typedef pair<int, int> pii; typedef pair<int, pii> piii; typedef pair<ll, ll> pll; typedef pair<ll, pll> plll; typedef pair<ll, int> pli; typedef pair<ll, pii> plii; template<class A, class B> bool maximize(A& x, B y) { if (x <= y) return x = y, true; else return false; } template<class A, class B> bool minimize(A& x, B y) { if (x > y) return x = y, true; else return false; } /* END OF TEMPLATE */ const int N = 100007; int n, k, a[N]; ll pre[N]; ll f[N], g[N]; int trace[207][N]; struct Line { ll a, b, id; Line() { a = b = 0; id = 0; } Line(ll a, ll b, int id) : a(a), b(b), id(id) {} ll GetVal(ll x) { return a * x + b; } }; // chu y trung` ho he so goc vector<pair<Line, long double>> E; long double GetIntersection(Line x, Line y) { return (long double)(y.b - x.b) / (x.a - y.a); } void addLine(Line x) { int n = E.size(); while (n > 1 && GetIntersection(x, E[n - 2].X) <= GetIntersection(E[n - 2].X, E[n - 1].X)) { n--; E.pop_back(); } if (n == 0) E.push_back({x, -1e18}); else E.push_back({x, GetIntersection(x, E[n - 1].X)}); } int idxE = 0; pair<ll, int> GetMin(int x) { if (E.empty()) return {-1e18, -1}; minimize(idxE, (int)E.size() - 1); while (idxE + 1 < (int)E.size() && E[idxE + 1].Y <= x) idxE++; int res = idxE; return {E[res].X.GetVal(x), E[res].X.id}; } int main() { // freopen("TEST.INP", "r", stdin); // freopen("TEST.OUT", "w", stdout); ios_base::sync_with_stdio(0); cin.tie(0); cin>>n>>k; FOR(i, 1, n) cin>>a[i], pre[i] = pre[i - 1] + a[i]; FOR(i, 0, n) g[i] = f[i] = -1e18; g[0] = 0; FOR(num, 1, k + 1) { idxE = 0; E.clear(); int i = 1; ll Max0 = g[0], idxMax0 = 0; while (i <= n) { if (pre[i] == 0) { f[i] = Max0; if (g[i] != -1e18 && maximize(Max0, g[i])) idxMax0 = i + 1; i++; continue; } else { if (num == 1) { f[i] = Max0; trace[num][i] = 1; } int j = i; while (j < n && pre[j] == pre[j + 1]) j++; ll Max = -1e18, idx = 0; // cout<<num<<" "<<i<<" "<<j<<"\n"; FOR(k, i, j) { pair<ll, int> val = GetMin(pre[k]); f[k] = val.X; trace[num][k] = val.Y; if (Max != -1e18 && maximize(f[k], Max + SQR(pre[k]))) trace[num][k] = idx + 1; if (Max0 > -1e18 && maximize(f[k], Max0)) trace[num][k] = idxMax0; if (g[k] != -1e18 && maximize(Max, g[k] - SQR(pre[k]))) idx = k; } if (Max != -1e18) addLine(Line(pre[idx], Max, idx + 1)); i = j + 1; } } FOR(i, 0, n) g[i] = f[i], f[i] = -1e18; // FOR(i, 1, n) { // FORD(j, i, 1) // if (dp[num - 1][j - 1] != -1e18) // if (maximize(dp[num][i], 1LL * (pre[i] - pre[j - 1]) * pre[j - 1] + dp[num - 1][j - 1])) trace[num][i] = j; // } } cout<<g[n]<<"\n"; vector<int> res; k++; while (trace[k][n] > 1 && k > 0) { res.push_back(trace[k][n] - 1); n = trace[k][n] - 1; k--; } reverse(all(res)); for (auto x : res) cout<<x<<" "; 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...