Submission #43644

#TimeUsernameProblemLanguageResultExecution timeMemory
43644sorry_BenqSplit the sequence (APIO14_sequence)C++14
0 / 100
16 ms16940 KiB
#include <bits/stdc++.h> using namespace std; typedef long long ll; ll S[10005]; ll DP[10005][205]; const ll INF = 1e18; int pointer; //Keeps track of the best line from previous query vector<long long> M; //Holds the slopes of the lines in the envelope vector<long long> B; //Holds the y-intercepts of the lines in the envelope //Returns true if either line l1 or line l3 is always better than line l2 bool bad(int l1,int l2,int l3) { /* intersection(l1,l2) has x-coordinate (b1-b2)/(m2-m1) intersection(l1,l3) has x-coordinate (b1-b3)/(m3-m1) set the former greater than the latter, and cross-multiply to eliminate division */ return (B[l3]-B[l1])*(M[l1]-M[l2])<(B[l2]-B[l1])*(M[l1]-M[l3]); } //Adds a new line (with lowest slope) to the structure void add(long long m,long long b) { //First, let's add it to the end M.push_back(m); B.push_back(b); //If the penultimate is now made irrelevant between the antepenultimate //and the ultimate, remove it. Repeat as many times as necessary while (M.size()>=3&&bad(M.size()-3,M.size()-2,M.size()-1)) { M.erase(M.end()-2); B.erase(B.end()-2); } } //Returns the minimum y-coordinate of any intersection between a given vertical //line and the lower envelope long long query(long long x) { //If we removed what was the best line for the previous query, then the //newly inserted line is now the best for that query if (pointer>=M.size()) pointer=M.size()-1; //Any better line must be to the right, since query values are //non-decreasing while (pointer<M.size()-1&& M[pointer+1]*x+B[pointer+1]<M[pointer]*x+B[pointer]) pointer++; return M[pointer]*x+B[pointer]; } int main(){ S[0] = 0; int N, K; cin >> N >> K; for (int i = 1; i <= N; i++){ ll x; cin >> x; S[i] = S[i - 1] + x; } for (int i = 1; i <= N; i++){ DP[i][1] = S[i]*S[i]; } for (int j = 2; j <= K + 1; j++){ pointer = 0; M.clear(); B.clear(); for (int i = j; i <= N; i++){ add(-2*S[i - 1], DP[i - 1][j - 1] + S[i - 1]*S[i - 1]); DP[i][j] = S[i]*S[i] + query(S[i]); } } int curpos = N; vector<int> idx; for (int j = K + 1; j >= 2; j--){ for (int i = curpos - 1; i >= 0; i--){ if (DP[curpos][j] == DP[i][j - 1] + (S[i] - S[curpos])*(S[i] - S[curpos])){ idx.push_back(i); curpos = i; break; } } } sort(idx.begin(), idx.end()); cout << (S[N] * S[N] - DP[N][K + 1])/2 << endl; for (int j: idx){ cout << j << ' '; } cout << endl; }

Compilation message (stderr)

sequence.cpp: In function 'long long int query(long long int)':
sequence.cpp:42:13: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  if (pointer>=M.size())
             ^
sequence.cpp:46:16: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  while (pointer<M.size()-1&&
                ^
#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...