제출 #1176736

#제출 시각아이디문제언어결과실행 시간메모리
1176736ivaziva수열 (APIO14_sequence)C++20
71 / 100
2097 ms43540 KiB
#pragma GCC optimize("Ofast") #include <bits/stdc++.h> using namespace std; #define MAXN 100001 #define MAXM 201 #define int long long #define ll long long bool Q=true; struct Line { mutable ll k, m, p; bool operator<(const Line& o) const { return Q ? p < o.p : k < o.k; } }; struct LineContainer : multiset<Line> { // (for doubles, use inf = 1/.0, div(a,b) = a/b) const ll inf = LLONG_MAX; ll div(ll a, ll b) { // floored division return a / b - ((a ^ b) < 0 && a % b); } bool isect(iterator x, iterator y) { if (y == end()) { x->p = inf; return false; } if (x->k == y->k) x->p = x->m > y->m ? inf : -inf; else x->p = div(y->m - x->m, x->k - y->k); return x->p >= y->p; } void addLine(ll k, ll m) { auto z = insert({k, m, 0}), y = z++, x = y; while (isect(y, z)) z = erase(z); if (x != begin() && isect(--x, y)) isect(x, y = erase(y)); while ((y = x) != begin() && (--x)->p >= y->p) isect(x, erase(y)); } pair<long long,long long> getMax(ll x) { assert(!empty()); Q = 1; auto l = *lower_bound({0,0,x}); Q = 0; return {l.k,l.m}; } }; int n,k; int pref[MAXN],dp[2][MAXN],where[MAXM][MAXN]; map<pair<int,int>,int> mapa; LineContainer tree; vector<int> ans; int eval(pair<int,int> linija,int x){return (long long)(linija.first*x)+linija.second;} int32_t main() { ios_base::sync_with_stdio(false); ios::sync_with_stdio(false); cin.tie(0);cout.tie(0);cin>>n>>k;pref[0]=0; for (int i=1;i<=n;i++) {cin>>pref[i];pref[i]+=pref[i-1];} for (int i=1;i<n;i++) dp[0][i]=(long long)(pref[i]*(pref[n]-pref[i])); for (int br=2;br<=k;br++) { for (int pos=br;pos<n;pos++) { tree.addLine(pref[pos-1],dp[0][pos-1]-(long long)(pref[pos-1]*pref[n])); mapa[{pref[pos-1],dp[0][pos-1]-(long long)(pref[pos-1]*pref[n])}]=pos-1; pair<int,int> resenje=tree.getMax(pref[pos]);dp[1][pos]=(long long)(pref[pos]*(pref[n]-pref[pos]))+eval(resenje,pref[pos]); where[br][pos]=mapa[resenje]; } for (int pos=br;pos<n;pos++) dp[0][pos]=dp[1][pos]; tree.clear();mapa.clear(); } int maks=dp[0][k],pos=k; for (int i=k+1;i<n;i++) { if (dp[0][i]>maks) {maks=dp[0][i];pos=i;} } cout<<maks<<endl;ans.push_back(pos); for (int i=k;i>=2;i--) {ans.push_back(where[i][pos]);pos=where[i][pos];} for (int pos=ans.size()-1;pos>=0;pos--) cout<<ans[pos]<<" "; cout<<endl;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...