Submission #231456

#TimeUsernameProblemLanguageResultExecution timeMemory
231456peijar수열 (APIO14_sequence)C++17
100 / 100
516 ms84320 KiB
#include <bits/stdc++.h>
using namespace std;

#define SZ(v) ((int)(v).size())
using ll = long long;
// convex hull, maximum
struct LineContainer
{
	struct Line
	{
		ll a, b;
		int id;
	};

	vector<Line> lines;
	int ptr;

	bool bad_line(Line l1, Line l2, Line l3)
	{
		return (long double)(l1.b - l3.b) * (l2.a - l1.a) <= (long double)(l1.b - l2.b) * (l3.a - l1.a);
	}

	// Increasing a !

	void add_line(ll a, ll b, int id)
	{
		Line l = {a, b, id};
		if (SZ(lines) and lines.back().a == l.a)
		{
			if (lines.back().b >= l.b)
				return ;
			lines.pop_back();
		}
		while (SZ(lines) >= 2 and bad_line(lines[SZ(lines) - 2], lines.back(), l))
			lines.pop_back();
		lines.push_back(l);
	}

	inline ll get_val(Line l, ll x)
	{
		return x * l.a + l.b;
	}

	// Increasing x !

	pair<ll, int> query(ll x)
	{
		assert(SZ(lines));
		ptr = min(SZ(lines) - 1, ptr);
		while (ptr + 1 < SZ(lines) and get_val(lines[ptr], x) <= get_val(lines[ptr+1], x))
			++ptr;
		return make_pair(get_val(lines[ptr], x), lines[ptr].id);
	}
};

const int MAXN = 1e5+1;
const int MAXK = 201;

ll dp[2][MAXN];

ll arr[MAXN];
int transition[MAXK][MAXN];
LineContainer cht;

int nb_elem;


int main(void)
{
	int nb_split;
	cin >> nb_elem >> nb_split;
	for (int i(0); i < nb_elem; ++i)
		cin >> arr[i];

	vector<ll> suffix_sum(nb_elem+1);
	suffix_sum[nb_elem] = 0;
	for (int i(nb_elem-1); i >= 0; --i)
		suffix_sum[i] = suffix_sum[i+1] + arr[i];

	for (int splits(1); splits <= nb_split; ++splits)
	{
		cht.lines.clear();
		int cur = splits%2;
		int prv = !cur;
		dp[cur][nb_elem-1] = -1;
		for (int id(nb_elem -2); id >= 0; --id)
		{
			if (dp[prv][id+1] >= 0)
				cht.add_line(suffix_sum[id+1], dp[prv][id+1] - suffix_sum[id+1] * suffix_sum[id+1], id);
			if (SZ(cht.lines))
			{
				auto [val, nxt] = cht.query(suffix_sum[id]);
				dp[cur][id] = val;
				transition[splits][id] = nxt;
			}
			else
				dp[cur][id] = -1;
		}
	}

	cout << dp[nb_split%2][0] << endl;

	int cur(0);
	for (int i(0); i < nb_split; ++i)
	{
		cur = transition[nb_split-i][cur] + 1;
		cout << cur << ' ';
	}
	cout << endl;

}
#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...