제출 #563287

#제출 시각아이디문제언어결과실행 시간메모리
563287piOOE수열 (APIO14_sequence)C++17
100 / 100
1120 ms88308 KiB
//#define _GLIBCXX_DEBUG //#pragma GCC optimize("Ofast") //#pragma GCC optimize("unroll-loops") //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native") #include <bits/stdc++.h> using namespace std; //#include <ext/pb_ds/assoc_container.hpp> // //using namespace __gnu_pbds; // //template<typename T> //using ordered_set = tree<T, null_type, less < T>, rb_tree_tag, tree_order_statistics_node_update>; //template<typename T> //using normal_queue = priority_queue<T, vector<T>, greater<>>; mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count()); #define trace(x) cout << #x << ": " << (x) << endl; #define all(x) begin(x), end(x) #define rall(x) rbegin(x), rend(x) #define uniq(x) x.resize(unique(all(x)) - begin(x)) #define sz(s) ((int) size(s)) #define pii pair<int, int> #define mp(x, y) make_pair(x, y) #define int128 __int128 #define pb push_back #define popb pop_back #define eb emplace_back #define fi first #define se second #define itn int typedef long long ll; typedef pair<ll, ll> pll; typedef long double ld; typedef double db; typedef unsigned int uint; template<typename T> bool ckmn(T &x, T y) { if (x > y) { x = y; return true; } return false; } template<typename T> bool ckmx(T &x, T y) { if (x < y) { x = y; return true; } return false; } int bit(int x, int b) { return (x >> b) & 1; } int rand(int l, int r) { return (int) ((ll) rnd() % (r - l + 1)) + l; } const ll infL = 3e18; const int infI = 1000000000 + 7; const int infM = 0x3f3f3f3f; //a little bigger than 1e9 const ll infML = 0x3f3f3f3f3f3f3f3fLL; //4.5e18 const int N = 100002; const int mod = 998244353; const ld eps = 1e-9; struct cht_min { struct line { ll k, b; int id; double f; line() = default; line(ll a, ll B, int gg) { k = a, b = B, id = gg; } double intersect(line now) const { return (ld) (b - now.b) / (now.k - k); } ll get(ll x) const { return k * x + b; } }; vector<line> d; int idx = 0; void add(line now) { while (d.size() > 1) { if (d.back().k == now.k) { if (d.back().b < now.b) { return; } } if (now.intersect(d.back()) > d.back().f) break; d.pop_back(); } if (!d.empty()) now.f = now.intersect(d.back()); else now.f = -infL; d.push_back(now); } pair<ll, int> get(ll x) { if (d.empty()) return {infL, -1}; idx = min(idx, (int) d.size() - 1); while (idx < (int) d.size() - 1 && d[idx].get(x) > d[idx + 1].get(x)) ++idx; return {d[idx].get(x), d[idx].id}; } }; int pref[N]; const int K = 201; ll dp[2][N]; int p[K][N]; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n, k; cin >> n >> k; for (int i = 1; i <= n; ++i) { cin >> pref[i]; pref[i] += pref[i - 1]; } //we need to minimize the squares of sums in each group for (int i = 1; i <= n; ++i) { dp[0][i] = pref[i] * 1LL * pref[i]; } memset(p, -1, sizeof(p)); for (int cut = 1; cut <= k; ++cut) { cht_min t; int nw = cut & 1; int pr = nw ^ 1; fill(dp[nw], dp[nw] + n + 1, infL); for (int i = 1; i <= cut; ++i) { t.add({-2 * pref[i], pref[i] * 1LL * pref[i] + dp[pr][i], i}); } for (int i = cut + 1; i <= n; ++i) { auto[ff, ss] = t.get(pref[i]); if (ff < infL) { ff += pref[i] * 1LL * pref[i]; if (ckmn(dp[nw][i], ff)) { p[cut][i] = ss; } t.add({-2 * pref[i], pref[i] * 1LL * pref[i] + dp[pr][i], i}); } } } vector<int> ans; for (int i = n, cut = k; i != -1;) { ans.push_back(i); i = p[cut--][i]; } reverse(all(ans)); ans.pop_back(); ll val = pref[n] * 1LL * pref[n] - dp[k & 1][n]; cout << val / 2 << '\n'; for (int x: ans) 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...