Submission #939315

#TimeUsernameProblemLanguageResultExecution timeMemory
939315iskhakkutbilimBuilding Bridges (CEOI17_building)C++17
100 / 100
106 ms52808 KiB
#include <bits/stdc++.h>
using namespace std;
#define ff first
#define ss second
#define all(a) a.begin(), a.end()
#define int long long
const int inf = 1e9;
const int N = 1e5 + 5;
const int mod = 1e9 + 7;
struct Line{
	int k, b;
	int operator * (int x){
		return k * x + b;
	}
	int operator ^ (Line x){
		return ceil((b - x.b) / (x.k - k));
	};
};

struct LiChao{
	Line tree[N * 30];
	int last, L[N * 30], R[N * 30];
	LiChao(){
		last = 0;
		for(int i=0;i<(N*30);i++) tree[i] = {inf, inf * inf};
	}
	
	void add(Line v, int lx = 0, int rx = mod, int x = 0){
		if(lx == rx){
			if(tree[x] * lx > v * lx) swap(tree[x], v);
			return;
		}
		if(v.k == tree[x].k){
			tree[x].b = min(tree[x].b, v.b);
			return;
		}
		
		int m = (lx + rx) >> 1;
		int ix = tree[x] ^ v;
		if(ix <= m){
			if(tree[x] * (m + 1) > v * (m + 1)) swap(tree[x], v);
			add(v, lx, m, (L[x] ? L[x] : L[x] = ++last));
		} else {
			if(tree[x] * m > v * m) swap(tree[x], v);
			add(v, m + 1, rx, (R[x] ? R[x] : R[x] = ++last));
		}
	}
	
	int get(int i, int lx = 0, int rx = mod, int x = 0){
		if(lx == rx) return tree[x] * i;
		int m = (lx + rx) >> 1;
		if(i <= m && L[x]) return min(tree[x] * i, get(i, lx, m, L[x]));
		if(m < i && R[x]) return min(tree[x] * i, get(i, m + 1, rx, R[x]));
		return tree[x] * i;
	}
}tree;
/*
6
3 8 7 1 6 6
0 -1 9 1 2 0
*/
signed main(){
	int n; cin >> n;
	vector<int> h(n+1);
	for(int i = 1;i <= n; i++) cin >> h[i];
	vector<int> w(n+1, 0);
	for(int i = 1;i <= n; i++){
		cin >> w[i];
		w[i]+= w[i-1];
	}
	
	vector<int> dp(n+1);
	dp[1] = 0;
	tree.add({-2 * h[1], dp[1] - w[1] + h[1] * h[1]});
	for(int i = 2;i <= n; i++){
			
		// kx + b
		/*
		
			new_dp[i] = (h[i] - h[j])^2 + dp[j]
			(h[i] - h[j]) * (h[i] - h[j]) = kx
			h[i] * h[i] - h[i] * h[j] - h[j] * h[i] + h[j] * h[j]
			dp[i] = min(dp[i], -2 * h[i] * h[j] + dp[j] - w[j] + h[j] * h[j] + w[i-1] + h[i] * h[i]);
		
		*/
		/*
		for(int j = 1; j < i; j++){
			//dp[i] = min(dp[i], -2 * h[i] * h[j] + dp[j] - w[j] + h[j] * h[j] + w[i-1] + h[i] * h[i]);
		}
		*/
		int mn = tree.get(h[i]);
		
		dp[i] = mn + h[i]*h[i] + w[i-1];
		tree.add({-2 * h[i], dp[i] - w[i] + h[i] * h[i]});
	}
	cout << dp[n];
	return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...