제출 #1028933

#제출 시각아이디문제언어결과실행 시간메모리
1028933borisAngelov수열 (APIO14_sequence)C++17
78 / 100
636 ms93156 KiB
#include <bits/stdc++.h> using namespace std; const int maxn = 100005; const int maxk = 205; const long long inf = (1LL << 63) - 1; int n, k; long long a[maxn]; long long pref[maxn]; long long dp[2][maxn]; int prvState[maxn][maxk]; long long sum(int from, int to) { return pref[to] - pref[from - 1]; } struct Line { long long a; long long b; int idx; long long calc(long long x) { return a * x + b; } }; struct ConvexHullTrickMAX { vector<pair<Line, double>> upperEnvelope; void reset() { upperEnvelope.clear(); } double cross(const Line& l1, const Line& l2) { return (1.0 * (l1.b - l2.b)) / (1.0 * (l2.a - l1.a)); } bool toRemove(const Line& newLine, pair<Line, double> last) { if (newLine.a == last.first.a) { return newLine.b >= last.first.b; } return cross(newLine, last.first) <= last.second; } void addLine(Line newLine) { while (upperEnvelope.size() > 1 && toRemove(newLine, upperEnvelope.back()) == true) { upperEnvelope.pop_back(); } if (upperEnvelope.empty()) { upperEnvelope.push_back({newLine, -inf}); } else { upperEnvelope.push_back({newLine, cross(newLine, upperEnvelope.back().first)}); } } Line query(long long x) { /*cout << "now query " << x << endl; for (auto [line, point] : upperEnvelope) { cout << line.idx << " " << point << endl; }*/ int l = 0; int r = upperEnvelope.size() - 1; while (l <= r) { int mid = (l + r) / 2; if (upperEnvelope[mid].second <= 1.0 * x) { l = mid + 1; } else { r = mid - 1; } } return upperEnvelope[r].first; } }; ConvexHullTrickMAX cht[2]; void fastIO() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); } int main() { fastIO(); cin >> n >> k; for (int i = 1; i <= n; ++i) { cin >> a[i]; pref[i] = pref[i - 1] + a[i]; } for (int j = 1; j <= k; ++j) { int curr = (j & 1); int prv = 1 - curr; cht[prv].reset(); for (int i = j; i <= n; ++i) { if (i > j) { Line best = cht[prv].query(pref[i]); dp[curr][i] = best.calc(pref[i]); prvState[i][j] = best.idx; } cht[prv].addLine({pref[i], dp[prv][i] - pref[i] * pref[i], i}); } } long long ans = dp[(k & 1)][n]; int pos = n; stack<int> splits; while (k > 0) { splits.push(prvState[pos][k]); pos = splits.top(); --k; } cout << ans << endl; while (!splits.empty()) { cout << splits.top() << " "; splits.pop(); } cout << endl; return 0; } /* 6 1 0 0 0 0 1 1 7 3 4 1 3 4 0 2 3 2 1 4 3 1 16 3 2 19 4 1 35 4 2 48 4 3 51 5 1 35 5 2 48 5 3 51 6 1 48 6 2 64 6 3 72 7 1 72 7 2 95 7 3 108 */

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

sequence.cpp:7:35: warning: integer overflow in expression of type 'long long int' results in '9223372036854775807' [-Woverflow]
    7 | const long long inf = (1LL << 63) - 1;
      |                       ~~~~~~~~~~~~^~~
#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...