记录编号 305187 评测结果 AAAAAAAAAA
题目名称 [NOI 2010]超级钢琴 最终得分 100
用户昵称 Gravatar农场主 是否通过 通过
代码语言 C++ 运行时间 3.909 s
提交时间 2016-09-10 17:04:18 内存使用 79.24 MiB
显示代码纯文本
#include<cstdio>
#include<algorithm>
#include<queue>
#include<vector>
#include<cmath>
#define maxn 1000000
using namespace std;
typedef long long ll;
class poi{
public:
	int x,l,r;
	ll val;
	bool operator () (poi a,poi b){
		return a.val<b.val;
	}
};
int n,k,l,r;
ll sum[maxn]={0};
int a[maxn];
int st[maxn][20];
int minv(int l,int r){
	if (sum[l]<sum[r]) return l;
	else return r;
}
void rmq(){
	for (int i=0;i<=n;i++){
		st[i][0]=i;
	}
	for (int i=1;(1<<i)<=n;i++){
		for (int j=0;(j+(1<<i)-1)<=n;j++){
			st[j][i]=minv(st[j][i-1],st[j+(1<<i-1)][i-1]);
		}
	}
}
int query(int l,int r){
	int t=1+log2(r-l+1),ans;
	if ((r-l+1)<(1<<t)) t--;
	ans=minv(st[l][t],st[r-(1<<t)+1][t]);
	return ans;
}

priority_queue<poi,vector<poi>,poi> pq; 
void read(){
	scanf("%d%d%d%d",&n,&k,&l,&r);
	for (int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		sum[i]=sum[i-1]+a[i];
	}
	rmq();
	for (int i=l;i<=n;i++){
		poi p;
		p.r=i-l; p.l=max(0,i-r); p.x=i;
		p.val=sum[p.x]-sum[query(p.l,p.r)];
//		printf("%d %d %d %d\n",p.x,p.l,p.r,p.val);
		pq.push(p);
	}
	int tot=0;
	ll ans=0;
	while (tot<k){
		poi p=pq.top(),a;
		pq.pop();
		int t=query(p.l,p.r);
		if (p.l<=t-1) {
			a.l=p.l;
			a.r=t-1;
			a.x=p.x;
			a.val=sum[a.x]-sum[query(a.l,a.r)];
			pq.push(a);
		}
		if (p.r>=t+1) {
			a.l=t+1;
			a.r=p.r;
			a.x=p.x;
			a.val=sum[a.x]-sum[query(a.l,a.r)];
			pq.push(a);
		}
		ans+=p.val;
		tot++;
	}
	printf("%lld",ans);
}

int main(){
	freopen("piano.in","r",stdin);
	freopen("piano.out","w",stdout);
	read();
	return 0;
}