Submission #1089756

#TimeUsernameProblemLanguageResultExecution timeMemory
1089756rlx0090Split the sequence (APIO14_sequence)C++14
100 / 100
1311 ms90444 KiB
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <cmath>
#include <limits>
#include <queue>
#include <string.h>
#include <stack>
#include <limits>
 
using namespace std;
int N, K;
int parent[205][100005];
long long p[100005], dp[2][100005];
long long inf = numeric_limits<long long>::max();
long long minf = numeric_limits<long long>::min();
struct line {
    long long m, k;
    double prev, next;
    int l;
    double cross(const line& o) {
        return 1.0 * (o.k - k) / (m - o.m);
    }
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    cin >> N >> K;
    //N = 3;
    //K = 2;
    long long q;
    for(int i = 1; i <= N; ++i) {
        cin >> q;
        //q = 1000;
        p[i] = p[i - 1] + q;
    }
    int pv = 0;
    int before = 0, cur = 0;
    for(int k = 1; k <= K; ++k) {
        before = k % 2; cur = (k + 1) % 2;
        vector<line> lines;
        
        for(int i = N - k - 1;  i >= 0; --i) {
            bool s = false;
            line new_line = {p[i + 1], -p[i + 1] * p[i + 1] + p[N] * p[i + 1] + dp[before][i + 1], inf, minf, i + 1};
            while(lines.size() > 0) {
                if(new_line.m == lines.back().m) {
                    if(new_line.k > lines.back().k) {
                        lines.pop_back();
                        if(lines.size() > 0) new_line.prev = new_line.cross(lines.back());
                    } else s = true;
                    break;
                }
                if((new_line.prev = new_line.cross(lines.back())) >= lines.back().prev)
                    lines.pop_back();
                else break;
            }
            if(!s && !lines.empty()) lines.back().next = lines.back().cross(new_line);
            //cout << i << "th push back line : " << new_line. m << ", " << new_line.k << ", " << new_line.prev << ", " << new_line.next << endl;
            //if(s) {cout << "before pv : " << pv << endl;}
            if(!s) lines.push_back(new_line);
        
            while(pv < lines.size() && lines[pv].next > p[i]) {
                //cout << "pv next : " << lines[pv].next << " pi : " << p[i] << endl; 
                ++pv;}
           // if(s) {cout << "after pv : " << pv << endl;}
            int z = lines.size() - 1;
            pv = min(z, pv);
            
            dp[cur][i] = p[i] * lines[pv].m + lines[pv].k - p[N] * p[i];
            //cout << i << "th lines size : " << lines.size() << " pv : " << pv << " v : " << dp[cur][i] << endl;
            //cout << "k : " << k << " i : " << i << " pv : " << pv << " c : " << dp[cur][i] << endl;
            //cout << p[i] * lines[pv].m << ", " << lines[pv].k << ", " << - p[N] * p[i] << endl;
            //cout << "p[n] : " << p[N] << " p[i] : " << p[i] << endl;
            //cout << "line m : " << lines[pv].m << " line k : " << lines[pv].k << " p i : " << p[i] << endl;
            parent[k][i] = lines[pv].l;
        }
        //cout << lines.size() << endl;
        //cout <<"kth opt : " << dp[cur][0] << endl;
    }
    cout << dp[cur][0] << '\n';
    int s = 0;
    for(int k = K; k >= 1; --k) {
        cout << parent[k][s] << ' ';
        s = parent[k][s];
    }
 
    return 0;
}

Compilation message (stderr)

sequence.cpp: In function 'int main()':
sequence.cpp:48:100: warning: narrowing conversion of 'inf' from 'long long int' to 'double' [-Wnarrowing]
   48 |             line new_line = {p[i + 1], -p[i + 1] * p[i + 1] + p[N] * p[i + 1] + dp[before][i + 1], inf, minf, i + 1};
      |                                                                                                    ^~~
sequence.cpp:48:105: warning: narrowing conversion of 'minf' from 'long long int' to 'double' [-Wnarrowing]
   48 |             line new_line = {p[i + 1], -p[i + 1] * p[i + 1] + p[N] * p[i + 1] + dp[before][i + 1], inf, minf, i + 1};
      |                                                                                                         ^~~~
sequence.cpp:66:22: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<line>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   66 |             while(pv < lines.size() && lines[pv].next > p[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...