제출 #556680

#제출 시각아이디문제언어결과실행 시간메모리
556680timreizin수열 (APIO14_sequence)C++17
100 / 100
723 ms87288 KiB
#pragma GCC optimize("Ofast,unroll-loops") #pragma GCC target("avx2,bmi,bmi2,popcnt,lzcnt") #include <iostream> #include <vector> #include <algorithm> #include <deque> #include <set> #include <string> #include <numeric> #include <cmath> #include <cassert> #include <array> #include <numeric> using namespace std; using ll = long long; const ll INF = 1e18; struct Line { ll k, b; int who; Line(ll k = 0, ll b = 0, int who = 0) : k(k), b(b), who(who) {} ll operator()(ll x) { return k * x + b; } }; bool check(Line a, Line b, Line c) { if (b.k == c.k) return b.b >= c.b; return (__int128)(a.b - c.b) * (b.k - a.k) <= (__int128)(a.b - b.b) * (c.k - a.k); } int main() { cin.tie(0)->sync_with_stdio(0); int n, k; cin >> n >> k; ++k; vector<ll> a(n); for (ll &i : a) cin >> i; array<vector<ll>, 2> dp; dp[0] = dp[1] = vector<ll>(n + 1, INF); dp[0][0] = 0; ll res = accumulate(a.begin(), a.end(), 0ll); res = res * res; partial_sum(a.begin(), a.end(), a.begin()); a.insert(a.begin(), 0); vector<vector<int>> parent(n + 1, vector<int>(k, -1)); auto dac = [&dp, &a, &parent](auto self, int l, int r, int l2, int r2, int level) { if (l > r) return; int m = (l + r) >> 1, ind = l2; for (int i = l2; i <= min(r2, m - 1); ++i) { ll cur = dp[0][i] + (a[m] - a[i]) * (a[m] - a[i]); if (cur < dp[1][m]) { dp[1][m] = cur; ind = i; } } parent[m][level] = ind; self(self, l, m - 1, l2, ind, level); self(self, m + 1, r, ind, r, level); }; for (int i = 0; i < k; ++i) { //dac(dac, i + 1, n, 0, n - 1, i); deque<Line> dq; dq.push_back({-2 * a[i], dp[0][i] + a[i] * a[i], i}); for (int j = i + 1; j <= n; ++j) { while (dq.size() >= 2 && dq[0](a[j]) > dq[1](a[j])) dq.pop_front(); dp[1][j] = dq.front()(a[j]) + a[j] * a[j]; parent[j][i] = dq.front().who; //add Line add{-2 * a[j], dp[0][j] + a[j] * a[j], j}; while (dq.size() >= 2 && check(dq[(int)dq.size() - 2], dq.back(), add)) dq.pop_back(); if (dq.back().k != add.k) dq.push_back(add); } //i -> i + 1 dp[0] = dp[1]; dp[1] = vector<ll>(n + 1, INF); } vector<int> path(k - 1); for (int i = k - 1, v = n; i > 0; v = parent[v][i], --i) path[k - i - 1] = parent[v][i]; cout << (res - dp[0].back()) / 2 << '\n'; reverse(path.begin(), path.end()); for (int i : path) cout << i << ' '; return 0; } /*dp[i] = min j < i dp[j] + (p[i] - p[j])^2 = dp[j] + p[j]^2 - 2p[j]*p[i] + p[i]^2 kx + b*/ /* 4 1 3 4 0 2 3 */

컴파일 시 표준 에러 (stderr) 메시지

sequence.cpp: In function 'int main()':
sequence.cpp:59:10: warning: variable 'dac' set but not used [-Wunused-but-set-variable]
   59 |     auto dac = [&dp, &a, &parent](auto self, int l, int r, int l2, int r2, int level)
      |          ^~~
#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...