申请做法
查看原帖
申请做法
905885
Him_shu楼主2025/2/6 11:44

用线段树代替单调栈,常数大,但简单一点

#include<bits/stdc++.h>
using namespace std;
#define int long long

#define ls(x) (x<<1)

#define rs(x) (x<<1|1)

#define mid ((l+r)/2)

inline int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-'){f=-1;}ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0',ch=getchar();}return x*f;}
void write(int x){if(x<0){putchar('-'),x=-x;}if(x>9){write(x/10);} putchar(x%10+'0');return;}
const int N=2e5+5,M=105,inf=1e14,mod=123456789;
int n,L;
int c[N],sum[N],dp[N];
struct Tree{
	int t[N<<2],lazy[N<<2];
	void pushup(int now){
		t[now]=max(t[ls(now)],t[rs(now)]);
	}
    void pushdown(int now,int l,int r){
        if(lazy[now]!=-inf){
            lazy[ls(now)]=lazy[now];
            lazy[rs(now)]=lazy[now];

            t[ls(now)]=lazy[now];
            t[rs(now)]=lazy[now];
            lazy[now]=-inf;
        }
    }
	void build(int now,int l,int r){
		lazy[now]=-inf;
		if(l==r){t[now]=0;return;}
		build(ls(now),l,mid);
		build(rs(now),mid+1,r);
		pushup(now);
	}
	void in(int now,int l,int r,int ql,int qr,int val){
        if(ql<=l&&r<=qr){t[now]=val,lazy[now]=val;return;}
        pushdown(now,l,r);
        if(ql<=mid)in(ls(now),l,mid,ql,qr,val);
        if(qr>mid)in(rs(now),mid+1,r,ql,qr,val);
        pushup(now);
	}
    int out(int now,int l,int r,int ql,int qr){
        if(ql<=l&&r<=qr)return t[now];
        pushdown(now,l,r);
        int sum=0;
        if(ql<=mid)sum+=out(ls(now),l,mid,ql,qr);
        if(qr>mid)sum+=out(rs(now),mid+1,r,ql,qr);
        return sum;
    }
}t;
int cal(int i,int j){
	return dp[i]+(j-(i+1)+sum[j]-sum[i]-L)*(j-(i+1)+sum[j]-sum[i]-L);
}
signed main(){
	cin>>n>>L;
	t.build(1,1,n);
	for(int i=1;i<=n;i++){
		cin>>c[i];
		sum[i]=sum[i-1]+c[i];
	}
	dp[1]=(c[1]-L)*(c[1]-L);
	for(int i=1;i<=n;i++){
		if(i>1)dp[i]=cal(t.out(1,1,n,i,i),i);
		int l=i+1,r=n,ret=-1;
		while(l<=r){
			if(cal(i,mid)<cal(t.out(1,1,n,mid,mid),mid)){
				ret=mid;
				r=mid-1;
			}
			else{
				l=mid+1;
			}
		}
		if(ret!=-1){t.in(1,1,n,ret,n,i);}
		
//		cout<<"决策表"<<i<<":";for(int j=1;j<=n;j++){cout<<t.out(1,1,n,j,j)<<" ";}cout<<"\n";
	}
//	cout<<"dp:";for(int i=1;i<=n;i++){cout<<dp[i]<<' ';}
	cout<<dp[n];
    return 0;
}
2025/2/6 11:44
加载中...