DP斜率优化
一行代码一行泪啊
不等式正负。。。
/*
WA N次原因:
1 不等式移向是没注意正负(!!!!!负数变号啊)
2 除法除数不能为0。。。
*/
/*
WA N次原因:
1 不等式移向是没注意正负(!!!!!负数变号啊)
2 除法除数不能为0。。。
*/
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<ctime>
#define LLMAX (long long)1E18
using namespace std;
long long a[1000011];
long long dp[1000011];
long long n,m,c;
long long x[1000011];
long long y[1000011];
long long p[1000011];
long long read()
{
long long k=0,f=1;
char c=getchar();
while(c>'9'||c<'0') {if(c=='-') f=-1; c=getchar();}
while(c>='0'&&c<='9') {k=k*10+(c-'0'); c=getchar();}
return k*f;
}
long double xl(long long y1,long long y2,long long x1,long long x2)
{
long double xx=x1-x2;
long double yy=y1-y2;
return (yy*1.0)/(xx*1.0);
}
int main()
{
// freopen("lx.in","r",stdin);
// freopen("lx.out","w",stdout);
long long i,j,k;
n=read();
m=read();
c=read();
for(i=1;i<=n;i++) dp[i]=LLMAX;
for(i=1;i<=n;i++)
{
a[i]=read();
}
sort(a+1,a+1+n);
// for(i=1;i<=n;i++)
// {
// x[i-1]=a[i]<<1;
// y[i-1]=a[i]*a[i];
// }
long long s,t;
long long head=1;
long long tail=1;
dp[0]=0;
for(i=m;i<=2*m-1;i++) dp[i]=c+(a[i]-a[1])*(a[i]-a[1]);
p[1]=0;
y[0]=dp[0]+a[1]*a[1];
for(i=2*m;i<=n;i++)
{
t=i-m;
y[t]=dp[t]+a[t+1]*a[t+1];
x[t]=a[t+1]<<1;
while(tail-head>0 && ((y[p[tail]]-y[p[tail-1]])*(x[t]-x[p[tail]])>=(y[t]-y[p[tail]])*(x[p[tail]]-x[p[tail-1]])))
tail--;
tail++;
p[tail]=t;
while(tail-head>0 && (y[p[head+1]]-y[p[head]])<=a[i]*(x[p[head+1]]-x[p[head]]))
head++;
dp[i]=c+dp[p[head]]+(a[i]-a[p[head]+1])*(a[i]-a[p[head]+1]);
}
cout<<dp[n];
return 0;
}