제출 #56943

#제출 시각아이디문제언어결과실행 시간메모리
56943Plurm수열 (APIO14_sequence)C++11
71 / 100
2072 ms105544 KiB
#include <cstdio>
#include <vector>
#include <algorithm>
#include <stack>
#include <tuple>
#define M(x) lines[x].first
#define C(x) lines[x].second
#define bad(x,y,z) ((C(y)-C(x))*(M(x)-M(z)) >= (C(z)-C(x))*(M(x)-M(y)))
using namespace std;
int a[100005];
long long dp[100005][2]; // End with i, having j parts;
int qs[100005];
int par[100005][256];
vector<pair<long long,long long> > lines;
vector<int> idx;
inline void add(int i,long long m, long long c){
	lines.emplace_back(m,c);
	idx.push_back(i);
	while(lines.size() >= 3 && bad(lines.size()-3, lines.size()-2, lines.size()-1)){
		lines.pop_back();
		lines.pop_back();
		lines.emplace_back(m,c);
		idx.pop_back();
		idx.pop_back();
		idx.push_back(i);
	}
}
int ptr;
inline pair<int,long long> query(long long x){
	if(ptr >= lines.size()) ptr = lines.size()-1;
	while(ptr < lines.size()-1 && M(ptr+1)*x + C(ptr+1) > M(ptr)*x + C(ptr)) ptr++;
	return make_pair(idx[ptr],M(ptr)*x + C(ptr));
}
inline int fastscan(){
	int x = 0;
	int c = getchar();
	while(c < 48 || c >= 58) c = getchar();
	while(c >= 48 && c < 58){
		x *= 10;
		x += c-48;
		c = getchar();
	}
	return x;
}
int main(){
	int n,k;
	n = fastscan();
	k = fastscan();
	k++;
	add(0,0,0);
	for(int i = 1; i <= n; i++){
		a[i] = fastscan();
		qs[i] = qs[i-1] + a[i];
		dp[i][0] = -1e16;
	}
	for(int j = 1; j <= k; j++){
		for(int i = max(1,j-1); i <= n; i++){
			if(i >= j)
				tie(par[i][j],dp[i][j % 2]) = query(qs[i]);
			add(i,(long long)qs[i], dp[i][(j+1) % 2] - (long long)qs[i]*(long long)qs[i]);
		}
		lines.clear();
		idx.clear();
		ptr = 0;
	}
	printf("%lld\n",dp[n][k % 2]);
	int x = n;
	stack<int> stk;
	for(int j = k; j > 1; j--){
		x = par[x][j];
		stk.push(x);
	}
	while(!stk.empty()){
		printf("%d ",stk.top());
		stk.pop();
	}
}

컴파일 시 표준 에러 (stderr) 메시지

sequence.cpp: In function 'std::pair<int, long long int> query(long long int)':
sequence.cpp:30:9: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  if(ptr >= lines.size()) ptr = lines.size()-1;
     ~~~~^~~~~~~~~~~~~~~
sequence.cpp:31:12: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  while(ptr < lines.size()-1 && M(ptr+1)*x + C(ptr+1) > M(ptr)*x + C(ptr)) ptr++;
        ~~~~^~~~~~~~~~~~~~~~
#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...