Comet OJ - Contest #7 D 机器学习题 斜率优化 + 未调完
Code:
#include <cstdio> #include <algorithm> #include <cstring> #define setIO(s) freopen(s".in","r",stdin) #define maxn 400005 #define inf 1000000009 #define ll long long using namespace std; int head,tail; int S[maxn]; ll le[maxn],ri[maxn],sumv[maxn],pos[maxn]; ll sqr(ll x) { return 1ll*(1ll*x * 1ll*x); } struct Node { ll x,y; }nd[maxn]; bool cmp(Node a,Node b) { return a.x<b.x; } ll Y(int f) { return (ll)(ri[f]+1ll*f*f); } ll X(int f) { return f; } double slope(int i,int j) { return (double)(Y(i)-Y(j))/(double)(X(i)-X(j)); } void insert(int x) { if(tail<2) { if(tail==1) { if(X(x)==XS[++tail]=x; } else { S[++tail]=x; } return; } while(tail>1&&slope(S[tail-1], S[tail]) >= slope(S[tail-1], x)) --tail; S[++tail]=x; } int main() { // setIO("input"); int n; scanf("%d",&n); for(int i=1;i<=n;++i) scanf("%lld%lld",&nd[i].x,&nd[i].y); sort(nd+1,nd+1+n,cmp); nd[0].x=-inf; for(int i=1;i<=n;++i) pos[i]=nd[i].x; for(int i=1;i<=n;++i) { sumv[i]=sumv[i-1]; if(nd[i].y<0) sumv[i]-=nd[i].y; le[i]=le[i-1]; if(nd[i-1].x!=nd[i].x) le[i]=sumv[i-1]; } for(int i=1;i<=n;++i) sumv[i]=0; nd[n+1].x=inf; for(int i=n;i>=1;--i) { sumv[i]=sumv[i+1]; if(nd[i].y>0) sumv[i]+=nd[i].y; ri[i]=ri[i+1]; if(nd[i+1].x!=nd[i].x) ri[i]=sumv[i+1]; } head=1; long long ans=100000000000000000; for(int i=1;i<=n;++i) insert(i); for(int i=1;i<=n;++i) { while(head<tail && pos[S[head]] < pos[i]) ++head; while(head<tail && slope(S[head], S[head+1]) < 2*pos[i]) ++head; if(head>tail) break; ans=min(ans, le[i] + sqr( (pos[i] - pos[S[head]]) ) + ri[S[head]]); // printf("%d %d %lld\n",i,S[head],ans); } printf("%lld\n",ans); return 0; }