이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <bits/stdc++.h>
#define ll long long
#define pb push_back
#define mp make_pair
#define ld long double
#define pll pair<ll,ll>
using namespace std;
const ld inf = 1e18;
const ll infll = 1e18;
const int maxn = 100100;
ll arr[maxn], pref[maxn];
ll dp[210][maxn], n, k;
ll parent[210][maxn];
const ll is_query = -(1LL<<62);
struct Line {
ll m, b, ind;
mutable function<const Line*()> succ;
bool operator<(const Line& rhs) const {
if (rhs.b != is_query) return m < rhs.m;
const Line* s = succ();
if (!s) return 0;
ll x = rhs.m;
return b - s->b < (s->m - m) * x;
}
};
struct HullDynamic : public multiset<Line> {
bool bad(iterator y) {
auto z = next(y);
if (y == begin()) {
if (z == end()) return 0;
return y->m == z->m && y->b <= z->b;
}
auto x = prev(y);
if (z == end()) return y->m == x->m && y->b <= x->b;
return 1.0 * (x->b - y->b)*(z->m - y->m) >= 1.0 * (y->b - z->b)*(y->m - x->m);
}
void insert_line(ll m, ll b, ll ind) {
auto y = insert({ m, b, ind});
y->succ = [=] { return next(y) == end() ? 0 : &*next(y); };
if (bad(y)) { erase(y); return; }
while (next(y) != end() && bad(next(y))) erase(next(y));
while (y != begin() && bad(prev(y))) erase(prev(y));
}
pll eval(ll x) {
auto l = *lower_bound((Line) { x, is_query });
return mp(l.m * x + l.b, l.ind);
}
};
int main() {
ios_base::sync_with_stdio(false);
cin.tie(0);
cin>>n>>k;
for(int i=1;i<=n;i++) {
cin>>arr[i];
pref[i] = pref[i-1] + arr[i];
}
for(int d=1;d<=k;d++) {
if(d == 1) {
for(int i=1;i<n;i++) {
dp[d][i] = pref[i] * (pref[n] - pref[i]);
}
continue;
}
HullDynamic ds;
for(int i=d;i<n;i++) {
// add info for state(d-1, i-1)
ds.insert_line(pref[i-1], dp[d-1][i-1] - pref[i-1]*pref[n], i-1);
pll curr = ds.eval(pref[i]);
dp[d][i] = curr.first + pref[i]*pref[n] - pref[i] * pref[i];
parent[d][i] = curr.second;
}
}
ll result = -inf;
ll resultind = -1;
for(int i=k;i<n;i++) {
if(dp[k][i] > result) {
result = dp[k][i];
resultind = i;
}
}
cout<<result<<"\n";
vector<int>v;
for(int i=k;i>=1;i--) {
v.pb(resultind);
resultind = parent[i][resultind];
}
reverse(v.begin(), v.end());
for(int i:v) {
cout<<i<<" ";
} cout<<"\n";
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |