Submission #637402

#TimeUsernameProblemLanguageResultExecution timeMemory
637402gromperenBuilding Bridges (CEOI17_building)C++14
100 / 100
52 ms8908 KiB
#include <bits/stdc++.h>
using namespace std;

#define ll long long

const ll INF = 1e18;

struct Line {
	ll m, b;
};

ll f(Line l, ll x) {
	return l.m * x + l.b;
}

struct Node {
	Line line;
	Node* lchild = nullptr;
	Node* rchild = nullptr;
};

ll query(Node* &node, ll x, int l = 0, int r = 1e6+5) {
	if (node == nullptr) return INF;
	int m = (l+r)/2;
	if (x <= m) 	return min(f(node->line, x), query(node->lchild, x, l, m));
	else 		return min(f(node->line, x), query(node->rchild, x, m+1, r));
}

void insert(Node* &node, Line nw, int l = 0, int r = 1e6+5) {
	if (node == nullptr) {
		node = new Node();
		node->line = nw;
		return;
	}
	int m = (l+r)/2;
	if (f(nw, m) < f(node->line, m)) swap(nw, node->line);
	if (f(nw, l) < f(node->line, l))
		insert(node->lchild, nw, l, m);
	if (f(nw, r) < f(node->line, r))
		insert(node->rchild,nw,m+1,r);
}

int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);

	int n; cin >> n;
	vector<ll> h(n+1), w(n+1);
	vector<ll> pre(n+1);
	for (int i = 1; i <= n; ++i) {
		cin>>h[i];
	}
	for (int i = 1; i <= n; ++i) {
		cin>>w[i];
		pre[i] = pre[i-1] + w[i];
	}
	vector<ll>dp(n+1);
	dp[1] = 0;
	w[1] = INF;
	Node* tree = nullptr;
	for (int i = 1; i <= n; ++i) {
		if (i > 1) dp[i] = query(tree, h[i]) + h[i] * h[i] + pre[i-1];
		Line ln;
		ln.m = -2*h[i];
		ln.b = dp[i] + h[i] * h[i] - pre[i];
		insert(tree, ln);
		//cout << dp[i] << " ";
	}
	cout << dp[n]<<"\n";

	return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...