洛谷 P4655 [CEOI2017]Building Bridges

由于点和斜率都没有单调性,要套一个 cdq 分治。没有什么坑点。

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>

typedef long long ll;

const int MAXN = 1e5 + 19;

struct Node{
	int id;
	ll x, y, k;
	ll w, h, w_;
}node[MAXN], tmp[MAXN];

inline ll sqr(const ll& a){
	return a * a;
}

inline bool cmp(const Node& a, const Node& b){
	return a.k < b.k;
}

int n;
ll dp[MAXN];

int Q[MAXN], head, tail;

void cdq(int l, int r){
	if(l == r){
		node[l].x = node[l].h;
		node[l].y = dp[l] - node[l].w + sqr(node[l].h);
		return;
	}
	int mid = (l + r) >> 1, p = l, q = mid + 1;
	for(int i = l; i <= r; ++i)
		if(node[i].id <= mid)
			tmp[p++] = node[i];
		else
			tmp[q++] = node[i];
	for(int i = l; i <= r; ++i)
		node[i] = tmp[i];
	cdq(l, mid);
	head = 1, tail = 0;
	for(int i = l; i <= mid; ++i){
		while(
			head < tail &&
			(node[i].y - node[Q[tail]].y) * (node[Q[tail]].x - node[Q[tail - 1]].x) <=
			(node[Q[tail]].y - node[Q[tail - 1]].y) * (node[i].x - node[Q[tail]].x)
		)
			--tail;
		Q[++tail] = i;
	}
	for(int i = mid + 1; i <= r; ++i){
		while(
			head < tail &&
			node[Q[head + 1]].y - node[Q[head]].y <=
			node[i].k * (node[Q[head + 1]].x - node[Q[head]].x)
		)
			++head;
		dp[node[i].id] = std::min(dp[node[i].id], dp[node[Q[head]].id] + sqr(node[i].h - node[Q[head]].h) + node[i].w_ - node[Q[head]].w);
	}
	cdq(mid + 1, r);
	int cnt = l; p = l, q = mid + 1;
	while(p <= mid && q <= r)
		if(node[p].x <= node[q].x)
			tmp[cnt++] = node[p++];
		else
			tmp[cnt++] = node[q++];
	while(p <= mid)
		tmp[cnt++] = node[p++];
	while(q <= r)
		tmp[cnt++] = node[q++];
	for(int i = l; i <= r; ++i)
		node[i] = tmp[i];
}

int main(){
	std::scanf("%d", &n);
	for(int i = 1; i <= n; ++i)
		std::scanf("%lld", &node[i].h), node[i].id = i, node[i].k = node[i].h * 2;
	for(int i = 1; i <= n; ++i)
		std::scanf("%lld", &node[i].w), node[i].w += node[i - 1].w, node[i].w_ = node[i - 1].w;
	std::sort(node + 1, node + 1 + n, cmp);
	std::memset(dp, 0x3f, sizeof dp); dp[1] = 0;
	cdq(1, n);
	std::printf("%lld\n", dp[n]);
	return 0;
}

猜你喜欢

转载自www.cnblogs.com/natsuka/p/12735754.html