제출 #396497

#제출 시각아이디문제언어결과실행 시간메모리
396497wind_reaper수열 (APIO14_sequence)C++17
0 / 100
188 ms9520 KiB
#include <bits/stdc++.h>

using namespace std;

const int64_t INF = 1e18;

template<typename T>
struct LiChaoTree{
	static const T identity = 0;

	struct Line{
		T m, c;

		Line(){
			m = 0;
			c = identity;
		}

		Line(T m, T c) : m(m), c(c) {}

		T val(T x){
			return m*x + c;
		}
	};

	struct Node{
		Node *lc, *rc;
		Line line;
		int idx;

		Node() : lc(0), rc(0) {}
	};

	deque<Node> buffer;

	Node* new_node(){
		buffer.emplace_back();
		return &buffer.back();
	}

	Node *root;

	T L, R;
	void init(T L, T R){
		this->L = L;
		this->R = R;

		root = new_node();
	}

	void insert(Node* &node, T l, T r, Line line, int idx){
		if(!node){
			node = new_node();
			node->line = line;
			node->idx = idx;
			return;
		}

		if(r - l == 1)
			return;

		T mid = (l + r) >> 1;
		
		if(line.val(mid) > node->line.val(mid)){
			swap(line, node->line);
			swap(idx, node->idx);
		}

		if(line.val(l) > node->line.val(l)) insert(node->lc, l, mid, line, idx);
		else insert(node->rc, mid, r, line, idx);
	}

	pair<T, int> query(Node* &node, T l, T r, T x){
		if(!node)
			return {identity, 0};

		T mid = (l + r) >> 1;
		pair<T, int> res = {node->line.val(x), node->idx};

		if(r - l == 1)
			return res;

		if(x < mid) return max(res, query(node->lc, l, mid, x));
		else return max(res, query(node->rc, mid, r, x));
	}

	void clear(){
		buffer.clear();
	}

	void insert(T m, T c, int idx) { insert(root, L, R, Line(m, c), idx); }
	pair<T, int> query(T x) { return query(root, L, R, x); }
};

int32_t main(){
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	int N, K;
	cin >> N >> K;

	vector<int64_t> pref(N+1);
	for(int i = 1; i <= N; i++){
		cin >> pref[i];
		pref[i] += pref[i-1];
	}

	LiChaoTree<int64_t> dp[2];
	vector<vector<int>> par(K+1, vector<int>(N+1, -1));

	for(int i = 0; i < 2; i++)
		dp[i].init(-1, INF);

	int64_t temp = 0;
	pair<int64_t, int> ans = {0, 0};

	for(int i = 1; i <= K; i++){
		int t = (i-1)&1;
		dp[t^1].clear();
		for(int j = 1; j < N; j++){
			pair<int64_t, int> q = dp[t].query(pref[N] - pref[j]); 
			temp = q.first + pref[j]*(pref[N] - pref[j]);
			int p = q.second;
			dp[t^1].insert(-pref[j], temp, j);
			ans = max(ans, {temp, j});
			par[i][j] = p;
		}
	}

	cout << ans.first << '\n';

	int nxt = ans.second;

	for(int i = K; i > 0; --i){
		cout << nxt << ' ';
		nxt = par[i][nxt];
	}

	return 0;
}
#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...