决策单调性优化dp二分队列做法0pts求调
查看原帖
决策单调性优化dp二分队列做法0pts求调
802878
Shattered_Shade楼主2024/6/1 00:35
#include<bits/stdc++.h>
#define int long long
#define lll __int128
using namespace std;
const int N=5e4+10;

int sum[N],f[N],t[N];
int n,L;

int w(int j,int i){
	return f[j]+(t[i]-t[j]-L)*(t[i]-t[j]-L);
}
bool better(int opt,int j,int i,bool eq){
	if(!eq) return w(j,opt)<w(i,opt);
	else return w(j,opt)<=w(i,opt);
}

int rt[N],lt[N];

void llz(){
	cin>>n>>L;
	L++;
	for(int i=1;i<=n;++i)cin>>sum[i];
	for(int i=1;i<=n;++i)sum[i]+=sum[i-1],t[i]=i+sum[i];
	deque<int> dq;
	dq.push_back(0);
	lt[0]=1,rt[0]=n;
	for(int i=1;i<=n;++i){
		while(dq.size()&&rt[dq.front()]<i)dq.pop_front();
		f[i]=w(dq.front(),i);
		lt[dq.front()]=i+1;
		while(dq.size()&&better(lt[dq.back()],i,dq.back(),false))dq.pop_back();
		if(!dq.size()){
			dq.push_back(i);
			lt[i]=i+1,rt[i]=n;
		}
		else if(better(rt[dq.back()],dq.back(),i,true)){
			if(rt[dq.back()]<n)dq.push_back(i),lt[i]=rt[dq.back()]+1,rt[i]=n;
		}
		else{
			int l=lt[dq.back()],r=rt[dq.back()];
			while(l<r){
				int mid=(l+r)>>1;
				if(better(mid,i,dq.back(),false))r=mid;
				else l=mid+1;
			}
			rt[dq.back()]=l-1;
			dq.push_back(i),lt[i]=l,rt[i]=n;
		}
	}
	cout<<f[n]<<"\n";
}

signed main(){
	iostream::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);	
	int T=1;
	while(T--)llz();
	return 0;
}
2024/6/1 00:35
加载中...