Submission #59068

#TimeUsernameProblemLanguageResultExecution timeMemory
59068zubecSplit the sequence (APIO14_sequence)C++14
50 / 100
21 ms2428 KiB
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;

ll n, m, a[1100], pref[1100], dp[1100][210];

struct line{
    ld k, b;
    int pos;
    //set<line>::iterator it;

    line(ld _k, ld _b, int _pos){
        k = _k;
        b = _b;
        pos = _pos;
    }

    ld eval(ld x){
        return k*x+b;
    }

};

inline ld intersect(line l1, line l2){
    return (l1.b-l2.b)/(l2.k-l1.k);
}

inline bool to_erase(line l1, line l2, line l3){
    ld x = intersect(l1, l3);
    return l2.eval(x) <= l3.eval(x);
    //return ((l3.b-l1.b)/(l1.k-l3.k) > (l3.b-l2.b)/(l2.k-l3.k));
}

vector <line> vec, vecCur;

void insrt(line ln){
    if (!vec.empty() && vec.back().k == ln.k){
        if (vec.back().b < ln.b)
            vec.pop_back(); else
            return;
    }
    while(vec.size() > 2 && to_erase(vec[vec.size()-2], vec[vec.size()-1], ln))
        vec.pop_back();
    vec.push_back(ln);
}

void rec(int n, int m){
    if (m == 0)
        return;
    for (int i = n-1; i >= 1; i--){
        if (dp[i][m-1] + (pref[n]-pref[i])*pref[i] == dp[n][m]){
            rec(i, m-1);
            cout << i << ' ';
            return;
        }
    }
}

void swp(){
    swap(vec, vecCur);
    vec.clear();
}

int main(){
    ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);

    cin >> n >> m;
    for (int i = 1; i <= n; i++){
        cin >> a[i];
        pref[i] = pref[i-1] + a[i];
    }
    for (int i = 0; i <= n; i++){
        for (int j = 1; j <= m; j++)
            dp[i][j] = -1e15;
    }
    for (int i = 1; i <= n; i++)
        insrt(line(pref[i], -(pref[i]*pref[i]), i));
    swp();
    for (int ii = 1; ii <= m; ii++){
        int pos = 0;
        for (int i = ii+1; i <= n; i++){
            while(pos+1 < vecCur.size() && vecCur[pos+1].pos < i && vecCur[pos].eval(pref[i]) <= vecCur[pos+1].eval(pref[i]))
                ++pos;
            dp[i][ii] = vecCur[pos].eval(pref[i]);
            //cout << i << ' ' << ii << ' ' << pos << ' ' << vecCur[pos].k << ' ' << vecCur[pos].b << endl;
            insrt(line(pref[i], dp[i][ii]-(pref[i]*pref[i]), i));
        }
        swp();
    }
    cout << dp[n][m] << endl;
    rec(n, m);

}

/**

7 3
4 1 3 4 0 2 3

*/

Compilation message (stderr)

sequence.cpp: In function 'int main()':
sequence.cpp:83:25: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
             while(pos+1 < vecCur.size() && vecCur[pos+1].pos < i && vecCur[pos].eval(pref[i]) <= vecCur[pos+1].eval(pref[i]))
                   ~~~~~~^~~~~~~~~~~~~~~
#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...