Ayiirep @ 2021-03-22 19:03:36
本地通过(用黄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;
}
by lqy520 @ 2021-03-22 19:23:12
黄lemon?
by Ayiirep @ 2021-03-22 19:38:33
@lqy520 就是 lemon
图标黄的那个 还有个lemon lime 是绿色的的...