# 【BZOJ2006】[NOI2010]超级钢琴

## Input

N<=500,000
k<=500,000
-1000<=Ai<=1000,1<=L<=R<=N且保证一定存在满足条件的乐曲

4 3 2 3
3
2
-6
8

## Sample Output

11
【样例说明】

#include <cstdio>
#include <iostream>
#include <queue>
#include <cstring>
#include <utility>
#define mp(A,B,C,D)	make_pair(make_pair(A,B),make_pair(C,D))
using namespace std;
typedef pair<int,int> pii;
priority_queue<pair<pii,pii> > pq;
int n,m,L,R;
long long ans;
const int maxn=500010;
int sn[maxn][20],v[maxn],s[maxn],Log[maxn];
int rd()
{
int ret=0,f=1;	char gc=getchar();
while(gc<'0'||gc>'9')	{if(gc=='-')f=-f;	gc=getchar();}
while(gc>='0'&&gc<='9')	ret=ret*10+gc-'0',gc=getchar();
return ret*f;
}
int mn(int a,int b)
{
return s[a]<s[b]?a:b;
}
int query(int a,int b)
{
if(a>b)	return -1;
int k=Log[b-a+1];
return mn(sn[a][k],sn[b-(1<<k)+1][k]);
}
int main()
{
n=rd(),m=rd(),L=rd(),R=rd();
int i,j,x,y,a,b,c,d;
for(i=2;i<=n;i++)	Log[i]=Log[i>>1]+1;
for(i=1;i<=n;i++)	sn[i][0]=i,v[i]=rd(),s[i]=v[i]+s[i-1];
for(j=1;(1<<j)<=n;j++)
for(i=0;i+(1<<j)-1<=n;i++)
sn[i][j]=mn(sn[i][j-1],sn[i+(1<<j-1)][j-1]);
for(i=L;i<=n;i++)	pq.push(mp(s[i]-s[query(max(i-R,0),i-L)],i,max(i-R,0),i-L));
for(i=1;i<=m;i++)
{
pii t1=pq.top().first,t2=pq.top().second;
ans+=t1.first,x=t1.second,a=t2.first,b=t2.second,y=query(a,b),pq.pop();
c=query(a,y-1),d=query(y+1,b);
if(c!=-1)	pq.push(mp(s[x]-s[c],x,a,y-1));
if(d!=-1)	pq.push(mp(s[x]-s[d],x,y+1,b));
}
printf("%lld",ans);
return 0;
}

posted @ 2017-06-23 19:10  CQzhangyu  阅读(1225)  评论(0编辑  收藏  举报