求助
查看原帖
求助
128870
chen_qian楼主2021/3/6 15:52

蒟蒻用李超线段树做这道题,竟然全部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
*/
2021/3/6 15:52
加载中...