悬关,10 pts 求调
查看原帖
悬关,10 pts 求调
678070
ykzzldz楼主2024/10/3 15:20

rt,或者给一个小一点的hack

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=5e5+10;
struct node{
	int numm,le,ri,pre,ww;
	bool operator<(node a)const{
		return pre<a.pre;
	}
};
priority_queue<node>q;
int f[N][30],num[N][30],n,k,l,r,sum[N],lg[30],ans;
int wz(int x,int y){
	int m=lg[y-x+1];
	if(f[x][m]>f[y-(1<<m)+1][m])return num[x][m];
	return num[y-(1<<m)+1][m];
}
void add(int po,int i,int ll,int rr){
	q.push({i,ll,rr,sum[po]-sum[i-1],po});
}
signed main(){
	cin>>n>>k>>l>>r;
	for(int i=1;i<=n;i++){
		cin>>sum[i];
		sum[i]+=sum[i-1];
		f[i][0]=sum[i];
		num[i][0]=i;
	}
	for(int i=2;i<=n;i++){
		lg[i]=lg[i/2]+1;
	}
	for(int j=1;j<=lg[n];j++){
		for(int i=1;i<=n-(1<<j)+1;i++){
			if(f[i][j-1]>f[i+(1<<(j-1))][j-1]){
				f[i][j]=f[i][j-1];
				num[i][j]=num[i][j-1];
			}
			else{
				f[i][j]=f[i+(1<<(j-1))][j-1];
				num[i][j]=num[i+(1<<(j-1))][j-1];
			}
		}
	}
	for(int i=1;i+l-1<=n;i++){
		add(wz(i+l-1,min(i+r-1,n)),i,i+l-1,min(i+r-1,n));
	}
	for(int j=1;j<=k;j++){
		node x=q.top();
		q.pop();
		ans+=x.pre;
		int w=x.ww,ll=x.le,rr=x.ri,i=x.numm;
		if(w!=ll)add(wz(ll,w-1),i,ll,w-1);
		if(w!=rr)add(wz(w+1,rr),i,w+1,rr);
	}
	cout<<ans<<'\n';
    return 0;
}
2024/10/3 15:20
加载中...