#include<bits/stdc++.h>
#define N 500005
using namespace std;
int n,k,l,r,a[N],s[N],maxn[N][20];
long long ans;
struct Heap
{
int i,l,r,val,pos;
bool operator<(const Heap & A) const
{return val<A.val;}
};
int Max(int x,int y)
{
return s[x]>s[y]?x:y;
}
int work(int l,int r)
{
int k=log2(double(r-l+1));
return Max(maxn[l][k],maxn[r-(1<<k)+1][k]);
}
priority_queue<Heap>heap;
int main()
{
scanf("%d%d%d%d",&n,&k,&l,&r);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
s[i]=s[i-1]+a[i];
maxn[i][0]=i;
}
for(int j=1;j<20;j++)
for(int i=1;i<=n+1-(1<<j);i++)
maxn[i][j]=Max(maxn[i][j-1],maxn[i+(1<<(j-1))][j-1]);
for(int i=1;i<=n;i++)
if(i+l-1<=n)
{
int ll=i+l-1;
int rr=min(i+r-1,n);
int pos=work(ll,rr);
int val=s[pos]-s[i-1];
heap.push((Heap){i,ll,rr,val,pos});
}else break;
while(!heap.empty()&&k--)
{
Heap now=heap.top();
heap.pop();
ans+=now.val;
Heap ll=now,rr=now;
ll.r=now.pos-1;
if(ll.r>=ll.l)
{
ll.pos=work(ll.l,ll.r);
ll.val=s[ll.pos]-s[ll.i-1];
heap.push(ll);
}
rr.l=now.pos+1;
if(rr.r>=rr.l)
{
rr.pos=work(rr.l,rr.r);
rr.val=s[rr.pos]-s[rr.i-1];
heap.push(rr);
}
}
printf("%lld\n",ans);
return 0;
}
NOI2010超级钢琴
原创
©著作权归作者所有:来自51CTO博客作者JackflyDC的原创作品,请联系作者获取转载授权,否则将追究法律责任
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
Luogu P2048 [NOI2010]超级钢琴
优先队列,ST表,堆
ST表 倍增 优先队列 i++ 四元组