李超线段树没过样例求条
查看原帖
李超线段树没过样例求条
1059849
tjx114514楼主2024/12/13 20:27

打了表看了一下,其他地方没有问题,错在李超线段树求最小值的部分

#include<bits/stdc++.h>
#define int long long
#define ls (x<<1)
#define rs (x<<1|1)
using namespace std;
const int MAXN=2e5+5;
int n,L,s[MAXN],dp[MAXN],a[MAXN],b[MAXN],c[MAXN<<2];
int g(int x,int o){return b[o]+a[o]*x;}
void upd(int x,int l,int r,int t){
	if(l==r){
		if(g(l,t)<g(l,c[x])) c[x]=t;
		return;
	}
	int mid=(l+r)>>1;
	if(g(mid,t)<g(mid,c[x])) swap(t,c[x]);
	if(g(l,t)<g(l,c[x])) upd(ls,l,mid,t);
	else if(g(r,t)<g(r,c[x])) upd(rs,mid+1,r,t);
}
int k;
int query(int x,int l,int r){
	if(l==r) return g(k,c[x]);
	int mid=(l+r)>>1;
	return min(g(k,c[x]),k<=mid?query(ls,l,mid):query(rs,mid+1,r));
}
signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin>>n>>L;++L;b[0]=1e18;
	for(int i=1;i<=n;i++) cin>>s[i],s[i]+=s[i-1]+1;
	dp[1]=(s[1]-L)*(s[1]-L);a[1]=s[1];b[1]=dp[1]+s[1]*s[1];upd(1,0,MAXN,1);
	for(int i=2;i<=n;i++){
		k=2*(L-s[i]);
		dp[i]=query(1,0,MAXN)+(s[i]-L)*(s[i]-L);
		a[i]=s[i];b[i]=dp[i]+s[i]*s[i];upd(1,0,MAXN,i);
	}
	cout<<dp[n];
	return 0;
}
2024/12/13 20:27
加载中...