답안 #939116

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
939116 2024-03-06T05:50:56 Z vjudge1 Building Bridges (CEOI17_building) C++17
100 / 100
106 ms 52052 KB
#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]);
		
		*/
		/*int ans = MAX;
		for(int j = 1; j < i; j++){
			ans = min(ans, -2 * h[i] * h[j] + dp[j] - w[j] + h[j] * h[j] + w[i-1] + h[i] * h[i]);
			//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]);
		
		//cout << i << " = " << ans << " , " << mn + h[i] * h[i] + w[i-1] << '\n';
		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;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 8 ms 47704 KB Output is correct
2 Correct 9 ms 47708 KB Output is correct
3 Correct 8 ms 47772 KB Output is correct
4 Correct 9 ms 47708 KB Output is correct
5 Correct 10 ms 47708 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 88 ms 50280 KB Output is correct
2 Correct 86 ms 50276 KB Output is correct
3 Correct 86 ms 50160 KB Output is correct
4 Correct 81 ms 50196 KB Output is correct
5 Correct 73 ms 51168 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 8 ms 47704 KB Output is correct
2 Correct 9 ms 47708 KB Output is correct
3 Correct 8 ms 47772 KB Output is correct
4 Correct 9 ms 47708 KB Output is correct
5 Correct 10 ms 47708 KB Output is correct
6 Correct 88 ms 50280 KB Output is correct
7 Correct 86 ms 50276 KB Output is correct
8 Correct 86 ms 50160 KB Output is correct
9 Correct 81 ms 50196 KB Output is correct
10 Correct 73 ms 51168 KB Output is correct
11 Correct 99 ms 51288 KB Output is correct
12 Correct 106 ms 51460 KB Output is correct
13 Correct 84 ms 50132 KB Output is correct
14 Correct 106 ms 51408 KB Output is correct
15 Correct 69 ms 52052 KB Output is correct
16 Correct 70 ms 51284 KB Output is correct
17 Correct 49 ms 50004 KB Output is correct
18 Correct 47 ms 50012 KB Output is correct