JZOJ 5409 Fantasy & NOI 2010 超级钢琴 题解
其实早在 2020-12-26 的比赛我们就做过 5409. Fantasy
这可是紫题啊
题目大意
给你一个序列,求长度在 \([L,R]\) 区间内的 \(k\) 个连续子序列的最大和
题解
如此多的子序列并不好处理
设 \(i\) 为一个区间的左端点,那么右端点的区间为 \([i+L-1,i+R-1]\) ,记前缀和为 \(sum_i\)
那么一个区间 \([i,j]\) 的和就是 \(sum_j-sum_{i-1}\) 已经知道左端点 \(sum_i\) ,只要找到最大的 \(sum_j\) 即可
所以可以用 \(\text{RMQ}\) 来解决查找问题。考虑把一个区间变成四元组 \(\{now,l,r,id\}\)
表示左端点 \(i\) 的位置,右端点的区间,区间 \([l,r]\) 中 \(j\) 的位置 。将一些四元组放入堆中
每次将堆顶的拆成两个 \(\{now,l,id-1,id_1\},\{now,pos+1,r,id_2\}\)
再放进堆中,原堆顶删除。\(id_1,id_2\) 都是 \(\text{RMQ}\) 实现,每次堆顶的值 \(sum_{id}-sum_{now-1}\) 的和就是答案
Code
#include<bits/stdc++.h>
using namespace std;
char buf[100000],*S=buf,*T=buf;
inline char Gc() {
return S==T&&(T=(S=buf)+fread(buf,1,100000,stdin),S==T)?EOF:*S++;
}
inline int Rd() {
register int o=0,f=0;
static char c=Gc();
for(;c<'0'||c>'9';c=Gc()) f|=c==45;
for(;c>'/'&&c<':';c=Gc()) o=(o<<1)+(o<<3)+(c^48);
return f?-o:o;
}
const int N=500005;
typedef long long LL;
int n,K,L,R,pw[35]={1},lg[N],sum[N],f[N][35];
LL ans;
inline int maxx(int x,int y) { return sum[x]>sum[y]?x:y; }
inline int RMQ(int l,int r) {
register int k=lg[r-l+1];
return maxx(f[l][k],f[r-pw[k]+1][k]);
}
struct node {
int x,l,r,id; node() { }
inline node(int _x,int _l,int _r):x(_x),l(_l),r(_r),id(RMQ(_l,_r)) { }
inline bool operator<(const node &o) const {
return sum[id]-sum[x-1]<sum[o.id]-sum[o.x-1]; }
}oo;
priority_queue<node>heap;
int main() {
// freopen("fantasy.in","r",stdin);
// freopen("fantasy.out","w",stdout);
for(int i=1;i<31;i++)pw[i]=pw[i-1]<<1;
n=Rd(),K=Rd(),L=Rd(),R=Rd();
for(int i=1;i<=n;i++)f[i][0]=i,sum[i]=sum[i-1]+Rd();
for(int i=2;i<=n;i++)lg[i]=lg[i>>1]+1;
for(int j=1;j<=lg[n];j++)
for(int i=0;i+pw[j-1]-1<=n;i++)
f[i][j]=maxx(f[i][j-1],f[i+pw[j-1]][j-1]);
for(int i=1;i<=n;i++)
if(i+L-1<=n)
heap.push(node(i,i+L-1,min(i+R-1,n)));
while(K--) {
oo=heap.top(),heap.pop(),ans+=1LL*sum[oo.id]-1LL*sum[oo.x-1];
if(oo.l^oo.id)heap.push(node(oo.x,oo.l,oo.id-1));
if(oo.id^oo.r)heap.push(node(oo.x,oo.id+1,oo.r));
}
printf("%lld",ans);
}
JZOJ 5409 Fantasy & NOI 2010 超级钢琴 题解的更多相关文章
- [BZOJ 2006] [NOI 2010]超级钢琴(贪心+ST表+堆)
[BZOJ 2006] [NOI 2010]超级钢琴(贪心+ST表+堆) 题面 给出一个长度为n的序列,选k段长度在L到R之间的区间,一个区间的值等于区间内所有元素之的和,使得k个区间的值之和最大.区 ...
- [NOI 2010]超级钢琴
Description 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙 的音乐. 这架超级钢琴可以弹奏出n个音符,编号为1至n.第i个音符的美妙 ...
- ●BZOJ 2006 NOI 2010 超级钢琴
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=2006 题解: RMQ + 优先队列 (+ 前缀) 记得在一两个月前,一次考试考了这个题目的简 ...
- 解题:NOI 2010 超级钢琴
题面 WC时候写的题,补一下 做法比较巧妙:记录每个位置和它当前对应区间的左右端点,做前缀和之后重载一下小于号,用优先队列+ST表维护当前最大值.这样贡献就是区间最大值和端点左边差分一下,可以O(1) ...
- BZOJ2006:[NOI2010]超级钢琴——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=2006 https://www.luogu.org/problemnew/show/P2048#su ...
- 洛谷P2048 [NOI2010]超级钢琴 题解
2019/11/14 更新日志: 近期发现这篇题解有点烂,更新一下,删繁就简,详细重点.代码多加了注释.就酱紫啦! 正解步骤 我们需要先算美妙度的前缀和,并初始化RMQ. 循环 \(i\) 从 \(1 ...
- JZOJ5409. Fantasy && Luogu2048 [NOI2010]超级钢琴
题目大意 给出一个序列和\(L, R\), 求前k大长度在\([L,R]\)之间的连续子序列的和的和. 解题思路 朴素的想法是对于一个左端点\(p\), 它的右区间取值范围是一个连续的区间即\([p+ ...
- 【NOI2010】超级钢琴 题解(贪心+堆+ST表)
题目链接 题目大意:求序列内长度在$[L,R]$范围内前$k$大子序列之和. ---------------------- 考略每个左端点$i$,合法的区间右端点在$[i+L,i+R]$内. 不妨暴力 ...
- 【题解】P2048 [NOI2010]超级钢琴
[题解][P2048 NOI2010]超级钢琴 一道非常套路的题目.是堆的套路题. 考虑前缀和,我们要是确定了左端点,就只需要在右端区间查询最大的那个加进来就好了.\(sum_j-sum_{i-1} ...
随机推荐
- HCIE笔记-第一节-网络的基本概念
R&S= 路由交换 Datacom =数通 =数据通信 某个设备产生了数据之后,借助整体的网络到达目的地的过程. 网络历史 -- 数通为什么产生? 1946年:世界上第一台计算机诞生.军事 科 ...
- OA办公软件篇(二)—权限管理
权限管理的背景 权限管理的作用 迭代历程 关键名词释义 权限管理模型 具体实现 写在最后 权限管理的背景 在OA办公软件篇(一)-组织架构一文中,我们说到组织架构是软件系统的权限体系的重要搭建依据 ...
- 数据库基础知识详解五:MySQL中的索引和其两种引擎、主从复制以及关系型/非关系型数据库
1.MySQL中的索引 在MySQL,索引是由B+树实现的,B+是一种与B树十分类似的数据结构. 形如下面这种: 其结构特点: (1)有n课子树的结点中含有n个关键码. (2)非根节点子节点数: ce ...
- hashMap、ConcurrentHashMap、hashTable、TreeMap、LinkedHashMap用法区别详解
Java集合中设计了一个接口Java.util.Map,它实现类中hashMap.hashTable.TreeMap.ConcurrentHashMap.LinkedHashMap. Map类型的集合 ...
- Linux的Docker安装教程
Docker下载的官方文档地址:https://docs.docker.com/engine/install/centos/ 卸载旧版本 sudo yum remove docker \ docker ...
- 在 ESXi 主机上关闭无响应的虚拟机电源
使用 ESXi 命令行 使用 SSH 以 root 身份登录到 ESXi. 通过运行以下命令获取所有已注册虚拟机的列表,由其 VMID 和显示名称标识: vim-cmd vmsvc/get ...
- 攻防世界-MISC:hit-the-core
这是攻防世界MISC高手进阶区的题目,题目如下: 点击下载附件一,解压后得到一个后缀为.core的文件,用string分离一下,得到如下结果: 通过观察发现,每隔四个小写字母就可以看到一个大写字母,刚 ...
- FreeRTOS --(2)内存管理 heap1
转载自https://blog.csdn.net/zhoutaopower/article/details/106631237 FreeRTOS 提供了5种内存堆管理方案,分别对应heap1/heap ...
- 斯坦福NLP课程 | 第2讲 - 词向量进阶
作者:韩信子@ShowMeAI,路遥@ShowMeAI,奇异果@ShowMeAI 教程地址:http://www.showmeai.tech/tutorials/36 本文地址:http://www. ...
- Android开发的开始
Android 软件 手机软件哦,目前只有一层外壳,进一步功能等待开发. 下载地址