蒟蒻求助
查看原帖
蒟蒻求助
234168
Ayiirep楼主2021/3/22 19:03

本地通过(用黄lemon测的),但是洛谷和loj都RE了QAQ....
洛谷RE了两个点...球球dalao帮忙看看...

#include <bits/stdc++.h>
//#define int long long
using namespace std;
#define temT template<typename T>
#define gc (getchar())
temT void rd(T &x) {
	x = 0; T f = 1; char ch = gc;
	while(!isdigit(ch) ) {if(ch == '-') f = -1; ch = gc;}
	while( isdigit(ch) ) x = x * 10 + ch - '0', ch = gc;
	x *= f;
}
#define FOR(i, a, b) for(int i = a; i <= b; ++i)
typedef long long lol;
const int N = 200005; 
const lol INF = 1e17;
const double eps = 1e-9;
int n;
lol h[N];
lol w[N], dp[N];
struct node {
	lol x, y, id;
	double slo;
	bool operator < (const node &b) const{return slo < b.slo || (slo == b.slo && x < b.x);}
};vector<node>vet; 
typedef vector<node>::iterator it;
double slope(lol ax, lol bx, lol ay, lol by) {
	if(ax == bx) return INF;
	return (double)(ay-by)/(ax-bx);
} 
int updatel(int L, int x, it &y) {
	lol nx = h[x], ny = dp[x]+1ll*h[x]*h[x]-w[x];
	while(L > 0 && vet[L-1].slo > slope(nx, vet[L].x, ny, vet[L].y)) L--, y--;
	return L;
}
int updater(int R, int x, it &y) {
	lol nx = h[x], ny = dp[x]+1ll*h[x]*h[x]-w[x];
	while(R < (int)vet.size()-1 && vet[R].slo < slope(nx, vet[R].x, ny, vet[R].y)) R++, y++;
	return R;
}
#define find(x) lower_bound(vet.begin(),vet.end(),vet[x])
void Insert(int x) {
	int L = 0, R = (int)vet.size()-1, mid, res = -1;
	while(L <= R) {
		mid = L+R>>1;
		if(vet[mid].x <= h[x]) res = mid, L = mid+1;
		else R = mid-1;
	}
	lol nx = h[x], ny = 1ll*h[x]*h[x]+dp[x]-w[x];
	if(vet[res].x == h[x] && ny < vet[res].y) {
		it i = find(res), j = i+1;
		int l = -1, r = (int)vet.size();
		if(res > 0) l = updatel(res-1, x, --i);
		if(res < r-1) r = updater(res+1, x, j);
		if(l < 0 && r > (int)vet.size()-1) {
			vet.clear(); vet.push_back((node){nx, ny, x, INF});
			return;
		}
		if(l < 0) {
			double slo = slope(nx, vet[r].x, ny, vet[r].y);
			vet.erase(vet.begin(), find(r));
			vet.insert(vet.begin(), (node){nx, ny, x, slo});
			return;
		}
		if(r > (int)vet.size()-1) {
			vet[l].slo = slope(vet[l].x, nx, vet[l].y, ny);
			vet.erase(find(l)+1, vet.end());
			vet.push_back((node){nx, ny, x, INF});
			return;
		}
		vet[l].slo = slope(nx, vet[l].x, ny, vet[l].y);
		double slo = slope(nx, vet[r].x, ny, vet[r].y);
		vet.erase(i+1, j);
		vet.insert(find(l)+1, (node){nx, ny, x, slo});
		return;
	}
	if(res == -1) {
		it j = vet.begin();
		int r = updater(0, x, j);
		double slo = slope(nx, j->x, ny, j->y);
		if(r>0) vet.erase(vet.begin(), j);
		vet.insert(vet.begin(), (node){nx, ny, x, slo});
	}
	else if(res == (int)vet.size()-1) {
		it i = vet.end()-1;
		int l = updatel(res, x, i);
		if(l < res) vet.erase(i+1, vet.end());
		i->slo = slope(nx, i->x, ny, i->y);
		vet.insert(find(l)+1, (node){nx, ny, x, INF});
	}
	else {
		it i = find(res), j = i+1;
		double sli = slope(nx, i->x, ny, i->y), slj = slope(nx, j->x, ny, j->y);
		if(sli >= slj) return;
		int l = updatel(res, x, i), r = updater(res+1, x, j);
		vet[l].slo = slope(nx, vet[l].x, ny, vet[l].y);
		double slo = slope(nx, vet[r].x, ny, vet[r].y);
		if(l < r-1)vet.erase(i+1, j);
		i = find(l)+1;
		vet.insert(find(l)+1, (node){nx, ny, x, slo});
	}
}
void Calc(int x) {
	it i = lower_bound(vet.begin(), vet.end(), (node){0, 0, 0, (double)2*h[x]});
	int y = i->id;
	dp[x] = dp[y]+1ll*(h[x]-h[y])*(h[x]-h[y])+w[x-1]-w[y];
	Insert(x);
}
signed main()
{
//	freopen("bridges.in","r",stdin);
//	freopen("bridges.out","w",stdout);
	rd(n); 
	FOR(i, 1, n) rd(h[i]); 
	FOR(i, 1, n) rd(w[i]), w[i] += w[i-1];
	dp[1] = 0; vet.push_back((node){h[1], 1ll*h[1]*h[1]-w[1], 1, (double)INF});
	FOR(i, 2, n) Calc(i);
	cout << dp[n];
	return 0;
}
2021/3/22 19:03
加载中...