比赛 20160909 评测结果 AAAAAAAAAA
题目名称 超级钢琴 最终得分 100
用户昵称 fg 运行时间 2.865 s
代码语言 C++ 内存使用 42.28 MiB
提交时间 2016-09-09 21:17:52
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<set>
#include<map>
#define mp(a,b,c,d) (data){a,b,c,d}
#define inf 1000000000
#define ll long long
#define N 500005
using namespace std;
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;
}
struct data{int i,l,r,t;};
int bin[20],Log[N];
int n,K,L,R;
int a[N],mx[N][20];
ll ans;
void pre()
{
	Log[0]=-1;for(int i=1;i<=n;i++)Log[i]=Log[i>>1]+1;
	for(int i=1;i<=n;i++)mx[i][0]=i;
	for(int i=n;i;i--)
		for(int j=1;j<=18;j++)
			if(i+bin[j]-1<=n)
			{
				int t1=mx[i][j-1],t2=mx[i+bin[j-1]][j-1];
				mx[i][j]=a[t1]>a[t2]?t1:t2;
			}
			else break;
}
inline int query(int l,int r)
{
	if(l==r)return l;
	int t=Log[r-l+1];
	int t1=mx[l][t],t2=mx[r-bin[t]+1][t];
	return a[t1]>a[t2]?t1:t2;
}
inline bool operator<(data x,data y)
{
	return a[x.t]-a[x.i-1]<a[y.t]-a[y.i-1];
}
void solve()
{
	priority_queue<data,vector<data> >q;
	for(int i=1;i<=n;i++)
		if(i+L-1<=n)
		{
			int t=min(n,i+R-1);
			q.push(mp(i,i+L-1,t,query(i+L-1,t)));
		}
	for(int i=1;i<=K;i++)
	{
		data t=q.top();q.pop();
		ans+=a[t.t]-a[t.i-1];
	    if(t.t-1>=t.l)q.push(mp(t.i,t.l,t.t-1,query(t.l,t.t-1)));
		if(t.t+1<=t.r)q.push(mp(t.i,t.t+1,t.r,query(t.t+1,t.r)));
	}
}
int main()
{
	freopen("piano.in","r",stdin);
	freopen("piano.out","w",stdout);
	bin[0]=1;for(int i=1;i<20;i++)bin[i]=bin[i-1]<<1;
	n=read();K=read();L=read();R=read();
	for(int i=1;i<=n;i++)a[i]=read();
	for(int i=1;i<=n;i++)a[i]+=a[i-1];
	pre();
	solve();
	printf("%lld",ans);
	return 0;
}