제출 #1203880

#제출 시각아이디문제언어결과실행 시간메모리
1203880Ghulam_Junaid수열 (APIO14_sequence)C++20
100 / 100
1868 ms89644 KiB
#include <bits/stdc++.h> using namespace std; #define F first #define S second #define inf 1e12 typedef long long ll; typedef pair<ll, ll> pii; const ll N = 1e5 + 10, K = 205; int n, k, a[N], par[N][K]; ll p[N]; vector<pair<ll, pii>> hull[K]; inline bool cmp(pii x, pii y){ if ((x.F / x.S) != (y.F / y.S)) return (x.F / x.S) > (y.F / y.S); x.F %= x.S; y.F %= y.S; return (x.F * y.S) > (y.F * x.S); } inline bool useful(pii x, pii y, pii z){ return cmp({x.S - y.S, y.F - x.F}, {y.S - z.S, z.F - y.F}); } inline void insert(int id, int ind, pii L){ while (hull[id].size() and hull[id].back().S.F == L.F){ if (hull[id].back().S.S < L.S) hull[id].pop_back(); else return ; } while (hull[id].size() > 1 and !useful(hull[id][hull[id].size() - 2].S, hull[id].back().S, L)) hull[id].pop_back(); hull[id].push_back({ind, L}); } inline ll f(pii L, ll x){ return x * L.F + L.S; } inline pair<ll, int> query(int id, int ind, ll x){ if (hull[id][0].F <= ind) return {-inf, -1}; pair<ll, int> ans = {f(hull[id][0].S, x), hull[id][0].F}; int lo = 0, hi = hull[id].size(); while (hi - lo > 1){ int mid = (lo + hi) / 2; if (hull[id][mid].F <= ind){ hi = mid; continue; } ll ans1 = f(hull[id][mid - 1].S, x); ll ans2 = f(hull[id][mid].S, x); if (ans1 < ans2){ ans = {ans2, hull[id][mid].F}; lo = mid; } else{ ans = {ans1, hull[id][mid - 1].F}; hi = mid; } } return ans; } int main(){ ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin >> n >> k; for (ll i = 1; i <= n; i ++) cin >> a[i], p[i] = p[i - 1] + a[i]; for (ll i = n; i > 0; i--) insert(k, i, {p[i - 1], 0 + p[n] * p[i - 1] -p[i - 1] * p[i - 1]}); ll val; for (ll kk = k - 1; kk >= 0; kk --){ for (ll i = n; i > 0; i --){ auto P = query(kk + 1, i, p[i - 1]); val = P.F - p[n] * p[i - 1], par[i][kk] = P.S; insert(kk, i, {p[i - 1], val + p[n] * p[i - 1] -p[i - 1] * p[i - 1]}); } hull[kk + 1].clear(); hull[kk + 1].shrink_to_fit(); } cout << val << '\n'; int cur = 1; for (int kk = 1; kk <= k; kk ++){ cur = par[cur][kk - 1]; cout << cur - 1 << " "; } cout << '\n'; }
#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...