# 2006: [NOI2010]超级钢琴

## 2006: [NOI2010]超级钢琴

Time Limit: 20 Sec  Memory Limit: 552 MB
Submit: 2634  Solved: 1313
[Submit][Status][Discuss]

## 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

【样例说明】

ST表请移步http://blog.csdn.net/insistgogo/article/details/9929103

#include<bits/stdc++.h>
#define ll long long
#define N 500010
using namespace std;
struct tri{
ll i,l,r,t;
}tmp;
ll n,k,L,R,a[N],Log[N],mx[N][20],bin[20],ans;
inline bool operator<(tri x,tri y)
{
return a[x.t]-a[x.i-1]<a[y.t]-a[y.i-1];
}
inline ll query(ll l,ll r)
{
if(l==r)return l;
ll t=Log[r-l+1];
ll t1=mx[l][t],t2=mx[r-bin[t]+1][t];
return a[t1]>a[t2]?t1:t2;
}
void pre()
{
Log[0]=-1;for(ll i=1;i<=n;i++)Log[i]=Log[i>>1]+1;
for(ll i=1;i<=n;i++)mx[i][0]=i;
for(ll i=n;i;i--)
for(ll j=1;j<=18;j++)
if(i+bin[j]-1<=n)
{
ll t1=mx[i][j-1],t2=mx[i+bin[j-1]][j-1];
mx[i][j]=a[t1]>a[t2]?t1:t2;
}
else break;
}
priority_queue<tri> q;
int main(){
bin[0]=1;for(ll i=1;i<20;i++)bin[i]=bin[i-1]<<1;
cin>>n>>k>>L>>R;
for (ll i=1;i<=n;i++) cin>>a[i],a[i]+=a[i-1];
pre();
for(ll i=1;i<=n;i++)
if(i+L-1<=n)
{
ll t=min(n,i+R-1);
q.push((tri){i,i+L-1,t,query(i+L-1,t)});
}
for(ll i=1;i<=k;i++)
{
tri t=q.top();q.pop();
ans+=a[t.t]-a[t.i-1];
if(t.t-1>=t.l)q.push((tri){t.i,t.l,t.t-1,query(t.l,t.t-1)});
if(t.t+1<=t.r)q.push((tri){t.i,t.t+1,t.r,query(t.t+1,t.r)});
}
cout<<ans;
}
View Code

posted @ 2017-01-22 07:42  xc01  阅读(93)  评论(0编辑  收藏  举报