제출 #921936

#제출 시각아이디문제언어결과실행 시간메모리
921936thangdz2k7수열 (APIO14_sequence)C++17
71 / 100
361 ms131072 KiB
#include <bits/stdc++.h>
#define int long long
#define ll long long
#define line pair <__int128, __int128>
#define double __int128
#define Point pair <double, double>
#define A first
#define B second
#define pb push_back

using namespace std;

const int N = 1e5 + 5;
const ll inf = 1e18;

int n, k;
int a[N], pre[N], best[205][N];
ll dp[2][N];

vector <line> st;
vector <int> idx;

Point giao(line l1, line l2){
    Point ans;
    double del = double (l1.A) - double(l2.A);
    ans.A = double (l2.B - l1.B) / del;
    ans.B = double (ans.A) * l1.A + l1.B;
    return ans;
}

void add(line p, int id){
    if (st.empty()){
        st.pb(p);
        idx.pb(id);
        return;
    }
    while (p.A == st.back().A) return;

    while (true){
        int sz = st.size();
        if (sz <= 1) break;
        line l2 = st.back();
        line l3 = st[sz - 2];
        Point k = giao(p, l3);
        if (k.A * l2.A + l2.B > k.B) break;
        st.pop_back();
        idx.pop_back();

    }
    st.pb(p);
    idx.pb(id);

}

int get(int &cur, int t, int i){
    int sz = st.size();
    cur = min(cur, sz - 1);
    dp[t][i] = st[cur].A * pre[i] + st[cur].B;
    while (cur < sz - 1){
        ll val = st[cur + 1].A * pre[i] + st[cur + 1].B;
        if (dp[t][i] < val){
            dp[t][i] = val;
            ++ cur;
        }
        else return idx[cur];
    }
    return idx[cur];
}

void solve(){
    cin >> n >> k;
    for (int i = 1; i <= n; ++ i){
        cin >> a[i];
        pre[i] = pre[i - 1] + a[i];
    }

    for (int loops = 1; loops <= k; ++ loops){
        st.clear();
        idx.clear();
        int t = loops & 1;
        int cur = 0;
        for (int i = 1; i <= n; ++ i){
            if (i == loops){
                add(line(pre[i], dp[1 ^ t][i] - pre[i] * pre[i]), i);
                best[loops][i] = i;
            }
            if (i > loops){
                dp[t][i] = inf;
                best[loops][i] = get(cur, t, i);
                add(line(pre[i], dp[1 ^ t][i] - pre[i] * pre[i]), i);
                //cout << loops << ' ' << i << ' ' << dp[t][i] << endl;
            }
        }
    }

    //cout << inf * inf;

    cout << dp[k & 1][n] << '\n';
    int cur = n;
    for (int i = k; i >= 1; -- i){
        cur = best[i][cur];
        cout << cur << ' ';
    }
}

signed main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    solve();
    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...