蒟蒻用李超线段树做这道题,竟然全部WA了?
#include<bits/stdc++.h>
#define N 50005
#define M 100005
#define int long long
using namespace std;
struct line{
int k,b;
}p[N<<1];
int s[M*4];
int L,c[N],sum[N],a[N],t[N],f[N],cnt;
int calc(int id,int x){
return p[id].b+p[id].k*a[x];
}
void modify(int u,int l,int r,int x){
int mid=(l+r)>>1;
int y=s[u];
int ansx=calc(x,mid),ansy=calc(y,mid);
if(l==r){
if(ansx<ansy) s[u]=x;
return ;
}
if(p[x].k>p[y].k){
if(ansx<ansy){
s[u]=x;
modify(u<<1|1,mid+1,r,y);
}
else modify(u<<1,l,mid,x);
}
else if(p[y].k>p[x].k){
if(ansx<ansy){
s[u]=x;
modify(u<<1,l,mid,y);
}
else modify(u<<1|1,mid+1,r,x);
}
else if(p[x].b<p[y].b) s[u]=x;
return;
}
int query(int u, int l,int r,int x){
int mid=(l+r)>>1;
int res=calc(s[u],x);
//cout<<s[u]<<' '<<x<<' '<<"qwq"<<' '<<res<<endl;
if(l==r) return res;
if(x<=mid) return min(res,query(u<<1,l,mid,x));
else return min(res,query(u<<1|1,mid+1,r,x));
}
signed main(){
int n;
scanf("%lld%lld",&n,&L);
for(int i=1;i<=n;i++){
int x;
scanf("%lld",&x);
sum[i]=sum[i-1]+x;
}
for(int i=0;i<=n;i++){
a[i]=sum[i]+i;
t[i]=sum[i]+i+L+1;
}
p[0].k=1000000000,p[0].b=10000000000;
f[1]=f[0]+a[1]*a[1]-2*a[1]*t[0]+t[0]*t[0];
//cout<<f[1]<<endl;
p[++cnt].k=-2*t[1];p[cnt].b=f[1]+t[1]*t[1];
modify(1,1,n,cnt);
for(int i=2;i<=n;i++){
f[i]=query(1,1,n,i)+a[i]*a[i];
//cout<<f[i]<<endl;
p[++cnt].k=-2*t[i];p[cnt].b=f[i]+t[i]*t[i];
modify(1,1,n,cnt);
}
printf("%lld",f[n]);
return 0;
}
/*
2 4
3
4
*/