题目链接

题目大意:求序列内长度在$[L,R]$范围内前$k$大子序列之和。

----------------------

考略每个左端点$i$,合法的区间右端点在$[i+L,i+R]$内。

不妨暴力枚举所有左端点,找到以其为左端点满足条件的最大子序列。

用贪心的思想,这些序列一定是满足题意的。统计后将该序列删除。

但这样直接删除肯定会丢失一部分有用的序列。一些也在前$k$大范围内的序列可能跟删除部分有交集。

所以我们不妨设$maxi$指以$i$为左端点的子序列,以$maxi$为右端点时能取得最大值。从此处将原先的大区间$[i+L,i+R]$裂解成两个区间$[i+L,maxi-1]$和$[maxi+1,i+R]$。从这两个区间中再找较大的满足条件的序列。

维护显然用堆。设一个五元组$(v,i,l,r,w)$表示以$i$为左端点,右端点在$[i+L,i+R]$内时,能找出以$w$为右端点的最大值为$v$的子序列。以$v$作为关键字,建立大根堆维护即可。

最后一个问题就是查找。我们不妨预处理出前缀和,用前缀和查找子序列的和。最大值用$ST$表维护。

代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=;
int f[N][],pos[N][];
int n,k,l,r,op;
long long ans;
int maxn,maxi;
struct node
{
int v,i,l,r,w;
}t,tmp;
bool operator <(const node &a,const node &b)
{
return a.v<b.v;
}
priority_queue<node> q;
inline void RMQ(int l,int r)
{
int opt=log2(r-l+);
if (f[l][opt]>=f[r-(<<opt)+][opt]) maxn=f[l][opt],maxi=pos[l][opt];
else maxn=f[r-(<<opt)+][opt],maxi=pos[r-(<<opt)+][opt];
}
signed main()
{
memset(f,,sizeof(f));
f[][]=;
scanf("%lld%lld%lld%lld",&n,&k,&l,&r);
op=log2(n);
for (int i=;i<=n;i++)
{
scanf("%lld",&f[i][]);
pos[i][]=i;
f[i][]+=f[i-][];
}
for (int t=;t<=op;t++)
for (int i=;i<=n;i++) if (i+(<<(t-))->n) break;
else
{
if (f[i][t-]>=f[i+(<<(t-))][t-]) f[i][t]=f[i][t-],pos[i][t]=pos[i][t-];
else f[i][t]=f[i+(<<(t-))][t-],pos[i][t]=pos[i+(<<(t-))][t-];
}
for (int i=;i<=n-l+;i++)
{
RMQ(i+l-,i+min(n-i,r-));
t.v=maxn-f[i-][],t.i=i,t.l=i+l-,t.r=i+min(n-i,r-),t.w=maxi;
q.push(t);
}
while(k--)
{
t=q.top();
q.pop();
ans+=t.v;
if (t.w>t.l)
{
RMQ(t.l,t.w-);
tmp.v=maxn-f[t.i-][],tmp.i=t.i,tmp.l=t.l,tmp.r=t.w-,tmp.w=maxi;
q.push(tmp);
}
if (t.w<t.r)
{
RMQ(t.w+,t.r);
tmp.v=maxn-f[t.i-][],tmp.i=t.i,tmp.l=t.w+,tmp.r=t.r,tmp.w=maxi;
q.push(tmp);
}
}
printf("%lld",ans);
return ;
}

【NOI2010】超级钢琴 题解(贪心+堆+ST表)的更多相关文章

  1. BZOJ_2006_[NOI2010]超级钢琴_贪心+堆+ST表

    BZOJ_2006_[NOI2010]超级钢琴_贪心+堆+ST表 Description 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的 音乐 ...

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

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

  3. BZOJ2006:[NOI2010]超级钢琴——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=2006 https://www.luogu.org/problemnew/show/P2048#su ...

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

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

  5. [NOI2010] 超级钢琴 - 贪心,堆,ST表

    这也算是第K大问题的套路题了(虽然我一开始还想了个假算法),大体想法就是先弄出最优的一批解,然后每次从中提出一个最优解并转移到一个次优解,用优先队列维护这个过程即可. 类似的问题很多,放在序列上的,放 ...

  6. 洛谷P2048 [NOI2010]超级钢琴 题解

    2019/11/14 更新日志: 近期发现这篇题解有点烂,更新一下,删繁就简,详细重点.代码多加了注释.就酱紫啦! 正解步骤 我们需要先算美妙度的前缀和,并初始化RMQ. 循环 \(i\) 从 \(1 ...

  7. BZOJ 2006 NOI2010 超级钢琴 划分树+堆

    题目大意:给定一个序列.找到k个长度在[l,r]之间的序列.使得和最大 暴力O(n^2logn),肯定过不去 看到这题的第一眼我OTZ了一下午... 后来研究了非常久别人的题解才弄明确怎么回事...蒟 ...

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

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

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

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

随机推荐

  1. [JAVA]使用字节流拷贝文件

    import java.io.*; /** * @Description: * @projectName:JavaTest * @see:PACKAGE_NAME * @author:郑晓龙 * @c ...

  2. 源码剖析@ApiImplicitParam对@RequestParam的required属性的侵入性

    问题起源 使用SpringCloud构建项目时,使用Swagger生成相应的接口文档是推荐的选项,Swagger能够提供页面访问,直接在网页上调试后端系统的接口, 非常方便.最近却遇到了一个有点困惑的 ...

  3. C#中关于Task.Yeild()的探究

    在与同事讨论async/await内部实现的时候,突然想到Task.Yeild()这个函数,为什么呢,了解一点C#async/await内部机制的都知道,在await一个异步任务(函数)的时候,它会先 ...

  4. scrapy shell 的使用

    是什么?:是一个终端下的调试工具,用来调试scrapy 安装ipython :pip install ipython 启动: scrapy shell + 需要请求的url 进来之后,response ...

  5. scrapy (三) : 请求传参

    scrapy 请求传参 1.定义数据结构item.py文件 ''' field: item.py ''' # -*- coding: utf-8 -*- # Define here the model ...

  6. 最大熵原理(The Maximum Entropy Principle)

    https://wanghuaishi.wordpress.com/2017/02/21/%E5%9B%BE%E8%A7%A3%E6%9C%80%E5%A4%A7%E7%86%B5%E5%8E%9F% ...

  7. python面向对象07/异常处理

    python面向对象07/异常处理 目录 python面向对象07/异常处理 1. 异常错误分类 2. 什么是异常? 3. 异常处理 4. 为什么要有异常处理 5. 异常处理的两种方式 1.if判断 ...

  8. JVM系列-方法调用的原理

    JVM系列-方法调用的原理 最近重新看了一些JVM方面的笔记和资料,收获颇丰,尤其解决了长久以来心中关于JVM方法管理的一些疑问.下面介绍一下JVM中有关方法调用的知识. 目的 方法调用,目的是选择方 ...

  9. css:实现文本两行或多行文本溢出显示省略号

    div{ display: -webkit-box; -webkit-box-orient: vertical; word-break: break-all; word-wrap: break-wor ...

  10. PagedList分页,如何添加action参数

    使用PagedList分页,如 @Html.PagedListPager((IPagedList)Model, page => Url.Action("Index", new ...