点此看题面

大致题意: 要你求出区间和前\(k\)大的区间的区间和之和,其中每个区间的大小在\(L\)与\(R\)之间。

堆+\(RMQ\)

这道题目,我们可以先对\(1\sim n\)中的每一个\(i\)假设它为左端点,求出区间\([i+L-1,min(i+R-1,n)]\)中的一个右端点\(s\),使得对于任意一个\(j∈[i+L-1,min(i+R-1,n)]\),满足\(\sum_{x=i}^s a[x]>=\sum_{y=i}^j a[y]\)(这可以直接对每个位置的前缀和求\(RMQ\))。

然后,将每个\([i+L-1,s]\)的区间和扔入一个中维护。

进一步思考

一起来观察一下下面这张图:

我们会发现,\([i+L-1,s-1]\)和\([s+1,min(i+R-1,n)]\)两个区间中也可能含有使答案区间和前\(k\)大的右端点,所以,对于一个答案,我们在将其统计之后,需要将它重新拆成两部分再分别扔回堆中,这样就能保证没有遗漏了。

代码

#include<bits/stdc++.h>
#define LL long long
#define N 500000
using namespace std;
int n,m,l,r,a[N+5],Log2[N+5];
LL sum[N+5];
struct RMQ//RMQ区间最值
{
LL Max,Maxer;//Max存储最大的数,Maxer存储最大的数的编号
bool operator < (const RMQ a) const//比较两个RMQ结构体的大小
{
return Max<a.Max;//比较最大的数的大小
}
}R[N+5][25];
struct key
{
LL x,y,s,val,pos;//x,y表示区间能选的范围,pos,s表示选择了的区间的范围,val表示这个选择了的区间的区间和
bool operator < (const key a) const//比较两个key结构体的大小
{
return val<a.val;//比较区间和的大小
}
};
priority_queue<key> h;//一个堆
inline char tc()
{
static char ff[100000],*A=ff,*B=ff;
return A==B&&(B=(A=ff)+fread(ff,1,100000,stdin),A==B)?EOF:*A++;
}
inline void read(int &x)
{
x=0;int f=1;char ch;
while(!isdigit(ch=tc())) if(ch=='-') f=-1;
while(x=(x<<3)+(x<<1)+ch-'0',isdigit(ch=tc()));
x*=f;
}
inline void write(LL x)
{
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);
putchar(x%10+'0');
}
inline void Start()//预处理
{
for(register int j=1;j<=25;++j)//预处理出RMQ
for(register int i=1;i+(1<<(j-1))<=n;++i)
R[i][j]=max(R[i][j-1],R[i+(1<<(j-1))][j-1]);
for(register int i=2;i<=n;++i) Log2[i]=Log2[i>>1]+1;//预处理出Log2[],减少精度误差
}
inline int Maxer(int l,int r)//返回这段区间内能使区间和最大的位置
{
int k=Log2[r-l+1];//一个RMQ的过程
return max(R[l][k],R[r-(1<<k)+1][k]).Maxer;
}
int main()
{
register int i;
for(read(n),read(m),read(l),read(r),i=1;i<=n;++i) read(a[i]),R[R[i][0].Maxer=i][0].Max=sum[i]=sum[i-1]+a[i];
Start();
for(i=1;i<=n-l+1;++i) h.push((key){i+l-1,(i+r-1<n?i+r-1:n),Maxer(i+l-1,(i+r-1<n?i+r-1:n)),sum[Maxer(i+l-1,(i+r-1<n?i+r-1:n))]-sum[i-1],i});//先将每一个区间加入堆
LL ans=0;//ans统计答案
while(m--)
{
key k=h.top();
h.pop(),ans+=k.val;//更新ans
if(k.x!=k.s) h.push((key){k.x,k.s-1,Maxer(k.x,k.s-1),sum[Maxer(k.x,k.s-1)]-sum[k.pos-1],k.pos});//若左边还有区间,就将左边一部分重新扔入堆中
if(k.s!=k.y) h.push((key){k.s+1,k.y,Maxer(k.s+1,k.y),sum[Maxer(k.s+1,k.y)]-sum[k.pos-1],k.pos});//若右边还有区间,就将右边一部分重新扔入堆中
}
return write(ans),0;
}

【BZOJ2006】[NOI2010] 超级钢琴(堆+RMQ)的更多相关文章

  1. BZOJ2006[NOI2010]超级钢琴——堆+主席树

    题目描述 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的 音乐. 这架超级钢琴可以弹奏出n个音符,编号为1至n.第i个音符的美妙度为Ai,其中 ...

  2. bzoj2006 [NOI2010]超级钢琴 (及其拓展)

    bzoj2006 [NOI2010]超级钢琴 给定一个序列,求长度在 \([L,\ R]\) 之间的区间和的前 \(k\) 大之和 \(n\leq5\times10^5,\ k\leq2\times1 ...

  3. BZOJ2006 [NOI2010]超级钢琴 【堆 + RMQ】

    2006: [NOI2010]超级钢琴 Time Limit: 20 Sec  Memory Limit: 552 MB Submit: 3446  Solved: 1692 [Submit][Sta ...

  4. P2048 [NOI2010]超级钢琴(RMQ+堆+贪心)

    P2048 [NOI2010]超级钢琴 区间和--->前缀和做差 多次查询区间和最大--->前缀和RMQ 每次取出最大的区间和--->堆 于是我们设个3元组$(o,l,r)$,表示左 ...

  5. [BZOJ2006][NOI2010]超级钢琴(ST表+堆)

    2006: [NOI2010]超级钢琴 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 3679  Solved: 1828[Submit][Statu ...

  6. bzoj千题计划162:bzoj2006: [NOI2010]超级钢琴

    http://www.lydsy.com/JudgeOnline/problem.php?id=2006 输出最大的k个 sum[r]-sum[l-1] (L<=r-l+1<=R) 之和 ...

  7. 【BZOJ 2006】2006: [NOI2010]超级钢琴(RMQ+优先队列)

    2006: [NOI2010]超级钢琴 Time Limit: 20 Sec  Memory Limit: 552 MBSubmit: 2792  Solved: 1388 Description 小 ...

  8. Bzoj 2006: [NOI2010]超级钢琴 堆,ST表

    2006: [NOI2010]超级钢琴 Time Limit: 20 Sec  Memory Limit: 552 MBSubmit: 2222  Solved: 1082[Submit][Statu ...

  9. [BZOJ2006] [NOI2010]超级钢琴 主席树+贪心+优先队列

    2006: [NOI2010]超级钢琴 Time Limit: 20 Sec  Memory Limit: 552 MBSubmit: 3591  Solved: 1780[Submit][Statu ...

  10. [NOI2010]超级钢琴(RMQ+堆)

    小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的音乐. 这架超级钢琴可以弹奏出n个音符,编号为1至n.第i个音符的美妙度为Ai,其中Ai可正可负 ...

随机推荐

  1. go语言web开发框架_Iris框架讲解(五)MVC包使用

    在Iris框架中,封装了mvc包作为对mvc架构的支持,方便开发者遵循mvc的开发原则进行开发. iris框架支持请求数据.模型.持久数据分层处理,并支持各层级模块代码绑定执行. MVC即:model ...

  2. LeetCode.11-装水最多的容器(Container With Most Water)

    这是悦乐书的第350次更新,第375篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Medium级别的第5题(顺位题号是11).给定n个非负整数a1,a2,-,an,其中每个表示坐标(i ...

  3. scapy框架

    性能相关 在编写爬虫时,性能的消耗主要在IO请求中,当单进程单线程模式下请求URL时必然会引起等待,从而使得请求整体变慢. import requests def fetch_async(url): ...

  4. .gitkeep--git提交空目录的解决方法

    前言 git和 svn不同,仅仅跟踪文件的变动,不跟踪目录.所以,一个空目录,如果里面没有文件,即便 git add 这个目录,另外在别处 check out 的时候,是没有这个空目录的. 只跟踪文件 ...

  5. POJ1151 Atlantis 线段树扫描线

    扫描线终于看懂了...咕咕了快三个月$qwq$ 对于所有的横线按纵坐标排序,矩阵靠下的线权值设为$1$,靠上的线权值设为$-1$,然后执行线段树区间加减,每次的贡献就是有效宽度乘上两次计算时的纵坐标之 ...

  6. 73th LeetCode Weekly Contest Rotated Digits

    X is a good number if after rotating each digit individually by 180 degrees, we get a valid number t ...

  7. Docker从入门到实战(一)

    Docker从入门到实战(一) 一:容器技术与Docker概念 1 什么是容器 容器技术并不是一个全新的概念,它又称为容器虚拟化.虚拟化技术目前主要有硬件虚拟化.半虚拟化.操作系统虚拟化等.1.1关于 ...

  8. Java面向对象_对象内存分析—值传递和引用传递

    对象内存分析,我一直学的比较模糊,今天抽空整理一下,希望能理清. 先说一下,内存分析从何而来,这对于我们这些刚接触java的人来说都比较模糊,就从new关键字说起吧. new关键字表示创建一个对象或者 ...

  9. (转)Linux下PS1、PS2、PS3、PS4使用详解

    Linux下PS1.PS2.PS3.PS4使用详解 原文:http://www.linuxidc.com/Linux/2016-10/136597.htm 1.PS1——默认提示符 如下所示,可以通过 ...

  10. 6 - 编码解码器-一种channelHandler

    6.1 解码器 6.1.1 抽象类-ByteToMessageDecoder decode(ChannelHandlerContext ctx, ByteBuf in, List<Object& ...