結果

問題 No.913 木の燃やし方
ユーザー ats5515ats5515
提出日時 2019-10-18 21:55:36
言語 C++11
(gcc 11.4.0)
結果
WA  
実行時間 -
コード長 3,575 bytes
コンパイル時間 1,633 ms
コンパイル使用メモリ 104,480 KB
実行使用メモリ 43,832 KB
最終ジャッジ日時 2024-06-25 15:57:23
合計ジャッジ時間 20,312 ms
ジャッジサーバーID
(参考情報)
judge4 / judge2
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
6,812 KB
testcase_01 AC 2 ms
6,940 KB
testcase_02 AC 2 ms
6,940 KB
testcase_03 WA -
testcase_04 WA -
testcase_05 AC 8 ms
6,944 KB
testcase_06 WA -
testcase_07 AC 5 ms
6,944 KB
testcase_08 AC 516 ms
35,932 KB
testcase_09 WA -
testcase_10 WA -
testcase_11 WA -
testcase_12 AC 619 ms
36,948 KB
testcase_13 AC 480 ms
37,840 KB
testcase_14 AC 463 ms
36,396 KB
testcase_15 AC 480 ms
36,368 KB
testcase_16 WA -
testcase_17 WA -
testcase_18 WA -
testcase_19 AC 375 ms
29,632 KB
testcase_20 AC 379 ms
29,604 KB
testcase_21 WA -
testcase_22 WA -
testcase_23 WA -
testcase_24 AC 382 ms
29,104 KB
testcase_25 AC 364 ms
29,664 KB
testcase_26 AC 531 ms
39,228 KB
testcase_27 AC 536 ms
43,832 KB
testcase_28 AC 447 ms
38,924 KB
testcase_29 AC 452 ms
38,936 KB
testcase_30 AC 444 ms
32,012 KB
testcase_31 AC 466 ms
40,960 KB
testcase_32 AC 467 ms
42,752 KB
testcase_33 AC 478 ms
42,368 KB
testcase_34 AC 440 ms
35,272 KB
testcase_35 AC 439 ms
35,288 KB
testcase_36 AC 377 ms
30,912 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <iostream>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <stdio.h>
#include <assert.h>
using namespace std;
#define int long long
template <typename T, bool isMin>
struct ConvexHullTrickWithIndex {
	struct P {
		T m, b;
		int idx;
		P(T m, T b, int idx) :m(m), b(b), idx(idx) {};
		bool operator<(const P &a) {
			return m != a.m ? m < a.m : b < a.b;
		}
	};

	deque<P> H;
	bool empty()const { return H.empty(); }
	void clear() { H.clear(); }

	inline int sgn(T x) { return x == 0 ? 0 : (x < 0 ? -1 : 1); }

	using D = long double;
	inline bool check(const P &a, const P &b, const P &c) {
		if (b.b == a.b || c.b == b.b)
			return sgn(b.m - a.m)*sgn(c.b - b.b) >= sgn(c.m - b.m)*sgn(b.b - a.b);
		return D(b.m - a.m)*sgn(c.b - b.b) / D(abs(b.b - a.b))
			>= D(c.m - b.m)*sgn(b.b - a.b) / D(abs(c.b - b.b));
	}

	void addLine(T m, T b, int idx) {
		if (!isMin) m *= -1, b *= -1;
		P line(m, b, idx);
		if (empty()) {
			H.emplace_front(line);
			return;
		}

		if (empty() || H.front().m <= m) {
			if (H.front().m == m) {
				if (H.front().b <= b) return;
				H.pop_front();
			}
			while (H.size() >= 2 && check(line, H.front(), H[1])) H.pop_front();
			H.emplace_front(line);
		}
		else {
			assert(m <= H.back().m);
			if (H.back().m == m) {
				if (H.back().b <= b) return;
				H.pop_back();
			}
			while (H.size() >= 2 && check(H[H.size() - 2], H.back(), line)) H.pop_back();
			H.emplace_back(line);
		}
	}

	inline pair<T, int> getY(const P &a, const T &x) {
		return make_pair(a.m*x + a.b, a.idx);
	}

	pair<T, int> query(T x) {
		assert(!empty());
		int l = -1, r = H.size() - 1;
		while (l + 1 < r) {
			int m = (l + r) >> 1;
			if (getY(H[m], x) >= getY(H[m + 1], x)) l = m;
			else r = m;
		}
		if (isMin) return getY(H[r], x);
		return make_pair(-getY(H[r], x).first, H[r].idx);
	}

	pair<T, int> queryMonotoneInc(T x) {
		assert(!empty());
		while (H.size() >= 2 && getY(H.front(), x) >= getY(H[1], x)) H.pop_front();
		if (isMin) return getY(H.front(), x);
		return make_pair(-getY(H.front(), x).first, H.front().idx);
	}

	pair<T, int> queryMonotoneDec(T x) {
		assert(!empty());
		while (H.size() >= 2 && getY(H.back(), x) >= getY(H[H.size() - 2], x)) H.pop_back();
		if (isMin) return getY(H.back(), x);
		return make_pair(-getY(H.back(), x).first, H.back().idx);
	}
};
vector<int> solve(int N, const vector<int> &A) {

	ConvexHullTrickWithIndex<int, true> cht;
	vector<vector<pair<int, int> > > X(N);
	vector<vector<pair<int, int> > > Y(N);
	int sum = 0;
	for (int i = 0; i < N; i++) {
		cht.addLine(-2 * (i - 1), -sum + (i - 1) * (i - 1), i);
		pair<int, int> p = cht.queryMonotoneInc(i);
		sum += A[i];
		p.first += i * i + sum;
		//cerr << p.first << " " << p.second << endl;
		X[p.second].push_back(make_pair(p.first, i));
		Y[i].push_back(make_pair(p.first, i));
	}
	vector<int> res(N);
	set <pair<int, int> > st;
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < X[i].size(); j++) {
			st.insert(X[i][j]);
		}
		res[i] = (*st.begin()).first;
		for (int j = 0; j < Y[i].size(); j++) {
			st.erase(Y[i][j]);
		}

	}
	return res;
}
signed main() {
	cin.tie(0);
	ios::sync_with_stdio(false);
	int N;
	cin >> N;
	vector<int> A(N);
	for (int i = 0; i < N; i++) {
		cin >> A[i];
	}
	vector<int> res = solve(N, A);
	reverse(A.begin(), A.end());
	vector<int> res2 = solve(N, A);
	reverse(res2.begin(), res2.end());
	for (int i = 0; i < N; i++) {
		res[i] = min(res[i], res2[i]);
	}
	for (int i = 0; i < N; i++) {
		cout << res[i] << endl;
	}
}
0