제출 #235826

#제출 시각아이디문제언어결과실행 시간메모리
235826balbit수열 (APIO14_sequence)C++14
100 / 100
1157 ms95352 KiB
#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define pii pair<int, int>
#define f first
#define s second

#define REP(i,n) for (int i = 0; i<n; ++i)
#ifdef BALBIT
#define bug(...) cerr<<"#"<<__LINE__<<": "<<#__VA_ARGS__<<": ", _do(__VA_ARGS__)
template<typename T> void _do(T && x){cerr<<x<<endl;}
template<typename T, typename ...S> void _do(T && x, S&&...y){cerr<<x<<", "; _do(y...);}
#define IOS()
#else
#define IOS() ios::sync_with_stdio(0), cin.tie(0)
#define endl '\n'
#define bug(...)
#endif // BALBIT

#define SZ(x) (int)(x.size())
#define ALL(x) (x).begin(), (x).end()
#define pb push_back

struct line{
    ll m,b;
    int id;
    line(ll m, ll b, int id): m(m), b(b), id(id){}
};

double its(line a, line b){
    if (a.m == b.m) return (a.b > b.b? -1 : -1 ) * (1e18+1029);
    return (b.b-a.b) / (double)(a.m-b.m);
}

deque<line>dq[203];

int frm[100005][203];
ll ps[100005];

void add(int k, int i, ll dp) {
    line td ((ll)2*ps[i], -(dp + ps[i] * ps[i]), i);
    // Everything is inverted for max hull
    while (SZ(dq[k]) >= 2) {
        if (td.m == dq[k].back().m && td.b <= dq[k].back().b) return;
        if (its(td, dq[k].back()) <= its(dq[k].back(), dq[k][SZ(dq[k]) - 2])) {
            dq[k].pop_back(); bug("popp");
        }else break;
    }
    dq[k].pb(td);
    bug(k, SZ(dq[k]));
}

pair<ll, int> qu(int k, int p) {
    while (SZ(dq[k]) >= 2 && (its(dq[k][0], dq[k][1])) <= p) {
        dq[k].pop_front(); bug("pop");
    }
    return {-(dq[k][0].m * p + dq[k][0].b), dq[k][0].id};
}

signed main(){
    IOS();
    int n,K; cin>>n>>K; ++K;
    assert(K >= 2);
    for (int i = 0; i<n; ++i) {
        cin>>ps[i+1]; ps[i+1] += ps[i];
    }
//    memset(dp, 0x3f, sizeof dp);
//    dp[0][0] = 0;
    // line (i,k) should be (ps[i], -(dp[i][k] + ps[i]^2), i)
    add(0,0,0);
    ll DP = -1;
     for (int i=1;i<=n;++i) {
////        vector<pair<int, ll> > toadd;
        for (int k=K; k>=1; --k){
            if (k > i) continue;
            pair<ll, int> q = qu(k-1,ps[i]);
            q.f += ps[i] * (ll)ps[i];
            frm[i][k] = q.s;
            assert(q.s < i);
            if (i == n && k == K) {
                DP = q.f;
            }else
                add(k,i,q.f);
            bug(i,k,q.f,q.s);
        }
//        for (int i = SZ(toadd)-1; i>=0; --i) {
//            add(k,toadd[i].f, toadd[i].s);
//        }
    }
//    bug(dp[n][K]);
    cout<<(ps[n]*ps[n] - DP) / 2<<endl;
    int at = frm[n][K];
    for (int k = K-1; k>0; --k) {
        cout<<at<<' ';
        at = frm[at][k];
    }
    cout<<endl;
}

/*
7 3
4 1 3 4 0 2 3
*/
#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...