結果

問題 No.2458 Line Up Charged Balls
ユーザー 沙耶花沙耶花
提出日時 2023-09-02 21:44:08
言語 C++17
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 137 ms / 2,000 ms
コード長 1,767 bytes
コンパイル時間 4,371 ms
コンパイル使用メモリ 262,528 KB
実行使用メモリ 8,104 KB
最終ジャッジ日時 2023-09-02 21:44:16
合計ジャッジ時間 8,003 ms
ジャッジサーバーID
(参考情報)
judge13 / judge14
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 1 ms
4,368 KB
testcase_01 AC 1 ms
4,368 KB
testcase_02 AC 2 ms
4,368 KB
testcase_03 AC 2 ms
4,368 KB
testcase_04 AC 1 ms
4,368 KB
testcase_05 AC 116 ms
7,880 KB
testcase_06 AC 118 ms
7,808 KB
testcase_07 AC 1 ms
4,372 KB
testcase_08 AC 2 ms
4,368 KB
testcase_09 AC 126 ms
7,440 KB
testcase_10 AC 35 ms
4,372 KB
testcase_11 AC 2 ms
4,372 KB
testcase_12 AC 3 ms
4,368 KB
testcase_13 AC 69 ms
5,424 KB
testcase_14 AC 70 ms
5,412 KB
testcase_15 AC 32 ms
4,956 KB
testcase_16 AC 96 ms
7,820 KB
testcase_17 AC 106 ms
7,796 KB
testcase_18 AC 102 ms
7,968 KB
testcase_19 AC 122 ms
8,104 KB
testcase_20 AC 107 ms
7,916 KB
testcase_21 AC 96 ms
7,964 KB
testcase_22 AC 98 ms
7,724 KB
testcase_23 AC 134 ms
7,840 KB
testcase_24 AC 110 ms
7,804 KB
testcase_25 AC 137 ms
7,832 KB
testcase_26 AC 122 ms
7,724 KB
testcase_27 AC 137 ms
7,828 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <stdio.h>
#include <atcoder/all>
#include <bits/stdc++.h>
using namespace std;
using namespace atcoder;
using mint = modint998244353;
#define rep(i,n) for (int i = 0; i < (n); ++i)
#define Inf32 1000000001
#define Inf64 4000000000000000001

/**
 * Author: Simon Lindholm
 * Date: 2017-04-20
 * License: CC0
 * Source: own work
 * Description: Container where you can add lines of the form kx+m, and query maximum values at points x.
 *  Useful for dynamic programming (``convex hull trick'').
 * Time: O(\log N)
 * Status: stress-tested
 */
using ll = long long;
struct Line {
	mutable ll k, m, p;
	bool operator<(const Line& o) const { return k < o.k; }
	bool operator<(ll x) const { return p < x; }
};

struct LineContainer : multiset<Line, less<>> {
	// (for doubles, use inf = 1/.0, div(a,b) = a/b)
	static const ll inf = LLONG_MAX;
	ll div(ll a, ll b) { // floored division
		return a / b - ((a ^ b) < 0 && a % b); }
	bool isect(iterator x, iterator y) {
		if (y == end()) return x->p = inf, 0;
		if (x->k == y->k) x->p = x->m > y->m ? inf : -inf;
		else x->p = div(y->m - x->m, x->k - y->k);
		return x->p >= y->p;
	}
	void add(ll k, ll m) {
		auto z = insert({k, m, 0}), y = z++, x = y;
		while (isect(y, z)) z = erase(z);
		if (x != begin() && isect(--x, y)) isect(x, y = erase(y));
		while ((y = x) != begin() && (--x)->p >= y->p)
			isect(x, erase(y));
	}
	ll query(ll x) {
		if(empty()){
			return -Inf64;
		}
		auto l = *lower_bound(x);
		return l.k * x + l.m;
	}
};


int main(){
	
	int n;
	cin>>n;
	vector<long long> q(n);
	rep(i,n)cin>>q[i];
	
	LineContainer L;
	vector<long long> dp(n);
	rep(i,n){
		dp[i] = max(dp[i],L.query(q[i]));
		L.add(q[i],dp[i]);
	}
	long long ans = 0;
	rep(i,n)ans = max(ans,dp[i]);
	cout<<ans<<endl;
	
	return 0;
}
0