【BZOJ】【P2006】【NOI2010】【超级钢琴】【题解】【堆+ST】
2014-09-06 10:44
267 查看
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2006
在堆里维护每个以i为左端点的区间,取出来一个区间[i,j]后,再加入[l,j-1]的max和[j+1,r]的max,l,r是指i向右可控制的范围
Code:
#include<bits/stdc++.h>
using namespace std;
const int maxn=5e5+10;
typedef pair<int,int> pii;
int n,k,L,R;
int a[maxn],sum[maxn];
int f[20][maxn],g[20][maxn];
long long ans=0;
void ST_init(){
int BIT=0;
for(int i=n;i;i>>=1,BIT++);
for(int i=1;i<=n;i++)f[0][i]=sum[i],g[0][i]=i;
for(int i=1;i<=BIT;i++)
for(int j=1;j<=n-(1<<i)+1;j++){
if(f[i-1][j]>f[i-1][j+(1<<i-1)])
f[i][j]=f[i-1][j],g[i][j]=g[i-1][j];
else f[i][j]=f[i-1][j+(1<<i-1)],g[i][j]=g[i-1][j+(1<<i-1)];
}
}
pii qmax(int l,int r){
int BIT=0;
for(int i=r-l+1;i;i>>=1,BIT++);BIT--;
if(f[BIT][l]>f[BIT][r-(1<<BIT)+1])return pii(g[BIT][l],f[BIT][l]);
else return pii(g[BIT][r-(1<<BIT)+1],f[BIT][r-(1<<BIT)+1]);
}
struct zky{
int i,j,l,r,v;
zky(int i=0,int j=0,int l=0,int r=0,int v=0):
i(i),j(j),l(l),r(r),v(v){}
bool operator<(const zky &sb)const{
return v<sb.v;
}
};
priority_queue<zky>q;
int main(){
scanf("%d%d%d%d",&n,&k,&L,&R);
for(int i=1;i<=n;i++)scanf("%d",a+i),sum[i]=sum[i-1]+a[i];
ST_init();
for(int i=1;i<=n;i++){
if(i-1+L>n)break;
pii x=qmax(i+L-1,min(i+R-1,n));
q.push(zky(i,x.first,i-1+L,min(i+R-1,n),x.second-sum[i-1]));
}
while(k--){
zky x=q.top();q.pop();
ans+=x.v;
if(x.j-1>=x.l){
pii t=qmax(x.l,x.j-1);
q.push(zky(x.i,t.first,x.l,x.j-1,t.second-sum[x.i-1]));
}
if(x.j+1<=x.r){
pii t=qmax(x.j+1,x.r);
q.push(zky(x.i,t.first,x.j+1,x.r,t.second-sum[x.i-1]));
}
}cout<<ans<<endl;
return 0;
}
在堆里维护每个以i为左端点的区间,取出来一个区间[i,j]后,再加入[l,j-1]的max和[j+1,r]的max,l,r是指i向右可控制的范围
Code:
#include<bits/stdc++.h>
using namespace std;
const int maxn=5e5+10;
typedef pair<int,int> pii;
int n,k,L,R;
int a[maxn],sum[maxn];
int f[20][maxn],g[20][maxn];
long long ans=0;
void ST_init(){
int BIT=0;
for(int i=n;i;i>>=1,BIT++);
for(int i=1;i<=n;i++)f[0][i]=sum[i],g[0][i]=i;
for(int i=1;i<=BIT;i++)
for(int j=1;j<=n-(1<<i)+1;j++){
if(f[i-1][j]>f[i-1][j+(1<<i-1)])
f[i][j]=f[i-1][j],g[i][j]=g[i-1][j];
else f[i][j]=f[i-1][j+(1<<i-1)],g[i][j]=g[i-1][j+(1<<i-1)];
}
}
pii qmax(int l,int r){
int BIT=0;
for(int i=r-l+1;i;i>>=1,BIT++);BIT--;
if(f[BIT][l]>f[BIT][r-(1<<BIT)+1])return pii(g[BIT][l],f[BIT][l]);
else return pii(g[BIT][r-(1<<BIT)+1],f[BIT][r-(1<<BIT)+1]);
}
struct zky{
int i,j,l,r,v;
zky(int i=0,int j=0,int l=0,int r=0,int v=0):
i(i),j(j),l(l),r(r),v(v){}
bool operator<(const zky &sb)const{
return v<sb.v;
}
};
priority_queue<zky>q;
int main(){
scanf("%d%d%d%d",&n,&k,&L,&R);
for(int i=1;i<=n;i++)scanf("%d",a+i),sum[i]=sum[i-1]+a[i];
ST_init();
for(int i=1;i<=n;i++){
if(i-1+L>n)break;
pii x=qmax(i+L-1,min(i+R-1,n));
q.push(zky(i,x.first,i-1+L,min(i+R-1,n),x.second-sum[i-1]));
}
while(k--){
zky x=q.top();q.pop();
ans+=x.v;
if(x.j-1>=x.l){
pii t=qmax(x.l,x.j-1);
q.push(zky(x.i,t.first,x.l,x.j-1,t.second-sum[x.i-1]));
}
if(x.j+1<=x.r){
pii t=qmax(x.j+1,x.r);
q.push(zky(x.i,t.first,x.j+1,x.r,t.second-sum[x.i-1]));
}
}cout<<ans<<endl;
return 0;
}
相关文章推荐
- 【BZOJ】2006 [NOI2010]超级钢琴 ST表+堆+贪心
- BZOJ 2006: [NOI2010]超级钢琴 [ST表+堆 | 主席树]
- 【BZOJ 2006】[NOI2010]超级钢琴 ST
- [BZOJ2006][NOI2010]超级钢琴(ST表+堆)
- bzoj 2006: [NOI2010]超级钢琴【st表+堆】
- [NOI2010][bzoj2006] 超级钢琴 [主席树/ST表+堆]
- [BZOJ2006][NOI2010]超级钢琴(st表+堆贪心)
- BZOJ 2006: [NOI2010]超级钢琴
- Bzoj 2006: [NOI2010]超级钢琴 堆,ST表
- bzoj2006 [NOI2010]超级钢琴
- 【题解】NOI-2010 超级钢琴
- BZOJ 2006: [NOI2010]超级钢琴
- BZOJ2006 [NOI2010]超级钢琴
- [bzoj2006][NOI2010]超级钢琴
- bzoj 2006: [NOI2010]超级钢琴 可持久化线段树+优先队列
- 【bzoj2006】[NOI2010]超级钢琴 堆+st表
- BZOJ 2006: [NOI2010]超级钢琴(ST表+优先队列)
- bzoj 2006: [NOI2010]超级钢琴
- bzoj2006: [NOI2010]超级钢琴(堆+RMQ)
- BZOJ2006: [NOI2010]超级钢琴