比赛 20160909 评测结果 WWWWEEEEEE
题目名称 超级钢琴 最终得分 0
用户昵称 旺仔小馒头 运行时间 2.737 s
代码语言 C++ 内存使用 419.14 MiB
提交时间 2016-09-09 21:57:39
显示代码纯文本
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<algorithm>
#define pa pair<int,int>
#define mk make_pair
#define maxn 500010
using namespace std;
int n,m,l,r,k,x,root[maxn],a[maxn],s[maxn],cnt[maxn],tot;
long long ans;
struct node{
	int sum,lc,rc;
}t[maxn*20*4];
priority_queue<pa>q;
int init(){
	int x=0,f=1;char s=getchar();
	while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
	while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
	return x*f;
}
int Build(int S,int L,int R){
	tot++;t[tot].sum=S;
	t[tot].lc=L;t[tot].rc=R;
	return tot;
}
void Insert(int &root,int pre,int pos,int l,int r){
	root=Build(t[root].sum+1,t[pre].lc,t[pre].rc);
	if(l==r)return;
	int mid=l+r>>1;
	if(pos<=mid)Insert(t[root].lc,t[pre].lc,pos,l,mid);
	else Insert(t[root].rc,t[pre].rc,pos,mid+1,r);
}
int Query(int L,int R,int k,int l,int r){
	if(l==r)return l;
	int sum=t[t[r].lc].sum-t[t[L].lc].sum;
	int mid=l+r>>1;
	if(sum>=k)return Query(t[L].lc,t[R].rc,k,l,mid);
	else return Query(t[L].rc,t[R].rc,k-sum,mid+1,r);
}
int main()
{
	freopen("piano.in","r",stdin);
	freopen("piano.out","w",stdout);
	n=init();k=init();l=init();r=init();
	for(int i=1;i<=n;i++){
		x=init();
		s[i]=s[i-1]+x;
		a[i]=s[i];
	}
	int num,pos,L,R,p,len,t;
	sort(a+1,a+1+n);
	num=unique(a+1,a+1+n)-a-1;
	for(int i=1;i<=n;i++){
		pos=lower_bound(a+1,a+1+num,s[i])-a;
		Insert(root[i],root[i-1],pos,1,num);
	}
	for(int i=1;i+l<=n;i++){
		L=i+l-1,R=min(n,i+r-1);
		len=R-L+1;++cnt[i];t=len-cnt[i]+1;
		pos=Query(root[L-1],root[R],t,1,num)-s[i-1];
		q.push(mk(a[pos],i));
	}
	for(int i=1;i<=k;i++){
		p=q.top().second;
		ans+=q.top().first;q.pop();
		L=p+l-1,R=min(n,p+r-1);
		len=R-L+1;++cnt[p];t=len-cnt[p]+1;
		pos=Query(root[L-1],root[R],t,1,num)-s[p-1];
		q.push(mk(a[pos],p));
	}
	printf("%lld\n",ans);
	return 0;
}