斜率优化 优化DP ,单调栈维护凸包即可
坐标轴旋转变成二维数点的套路
%:pragma GCC optimize(2)
#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 + 5;
struct Point {
int x , y , id;
friend bool operator < (Point xxx , Point yyy) {
return (xxx.x == yyy.x) ? xxx.y < yyy.y : xxx.x < yyy.x;
}
void input(int k) {
id = k; scanf("%d%d" , &x , &y);
}
}P[N] , Q[N];
bool cmp2(Point xxx , Point yyy) {
if(xxx.x != yyy.x) return xxx.x < yyy.x;
if(xxx.y != yyy.y) return xxx.y < yyy.y;
return xxx.id < yyy.id;
}
int n , m , x , y , cnt;
map <int , int> Map , C;
#define lowbit(x) (x & (-x))
const double eps = 1e-12;
int chg[N] , pos[N];
long long f[N] , g[N] , S[N];
void add(int x , long long v) {
for(int i = x;i < N;i += lowbit(i)) S[i] = max(S[i] , v);
}
long long sum(int x) {
long long res = 0;
for(int i = x;i;i -= lowbit(i)) res = max(res , S[i]);
return res;
}
vector <int> Stk[N];
#define b(x , y) x[(int)x.size() - y]
long long sqr(long long x) {
return x * x;
}
double calc(int a , int b) {
int A = a - 1 , B = b - 1;
return (double) (f[B + 1] - f[A + 1] - A * 1ll * A + B * 1ll * B) / 2. / (double)(B - A);
}
long long godance(int x) {
int now = x - pos[x] + 1;
//cerr << now << endl;
if(!Stk[now].size()) {
Stk[now].push_back(x); return 1;
}
while(Stk[now].size() > 1) {
if(calc(b(Stk[now] , 2) , b(Stk[now] , 1)) <= x + eps) Stk[now].pop_back();
else break;
}
long long res = f[b(Stk[now] , 1)] + sqr(x - b(Stk[now] , 1) + 1);
//cerr << x <<" "<< b(Stk[now] , 1) << endl;
while(Stk[now].size() > 1) {
if(calc(b(Stk[now] , 2) , b(Stk[now] , 1)) <= calc(b(Stk[now] , 1) , x)) Stk[now].pop_back();
else break;
}
Stk[now].push_back(x);
return res;
}
main(void) {
for(int i = scanf("%d" , &n);i <= n;++ i) P[i].input(i) , Q[i] = P[i] , Q[i].x = P[i].y + P[i].x , Q[i].y = P[i].y - P[i].x , ++ Map[Q[i].y];
for(map<int , int> ::iterator it = Map.begin(); it != Map.end();++ it) {
chg[++ cnt] = it -> first; C[it -> first] = cnt;
}
pos[1] = 1;
for(int i = 2;i <= n;++ i) {
if(abs(P[i].x - P[i - 1].x) <= abs(P[i].y - P[i - 1].y)) pos[i] = pos[i - 1] + 1;
else pos[i] = 1;
}
for(int i = 1;i <= n;++ i) Q[i].y = C[Q[i].y];
//for(int i = 1;i <= n;++ i) cerr << Q[i].y << endl;
sort(Q + 1 , Q + n + 1 , cmp2);
//for(int i = 1;i <= n;++ i)
long long ans = 0;
for(int i = 1;i <= n;++ i) {
int now = Q[i].id;
f[now] = sum(Q[i].y);
g[now] = godance(now);g[now] = max(g[now] , f[now] + 1);
//for(int j = now - pos[now] + 1;j <= now;++ j) g[now] = max(g[now] , (now - j + 1) * (now - j + 1) + f[j]);
ans = max(ans , f[now]); ans = max(ans , g[now]);
add(Q[i].y , g[now]);
}
cout << ans << endl;
}
出题人考察选手的基本优化DP能力