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} ...
随机推荐
- E-R图转换为关系模型
E-R模型如何转换成关系模型,这里我们分成三种情况进行讲解,分别是一对一,一对多和多对多. 1.一对一的情况: 有两种方法解决这个问题.第一个方法:可以单独对应一个关系模式,由各实体的主码构成关系模式 ...
- 整合SSM框架环境搭建
知识要求 MySQL相关操作 Maven操作 Mybatis.Spring.SpringMVC三个框架基本操作 JavaWeb等知识 搭建环境 MySQL 8.0 Mybatis 3.5.2 使用c3 ...
- Python自动批量修改服务器密码
工作中,我们经常会定期更换服务器密码,如果手动去修改,不仅费时,而且容易出错.下面提供了一种思路,可以实现批量.自动修改服务器密码. 大致思路:首先,为每一台服务器设定一个唯一标识:其次,将每台服务器 ...
- Linux Red Hat 8.0虚拟机安装过程
Linux Red Hat 8.0虚拟机安装过程 一.安装虚拟机所需要的工具: 1.VMware Workstation Pro 2.Red Hat 8.0 虚拟机镜像 3.还有一个就是VMware的 ...
- QT的MYSQL驱动库编译
QT的MYSQL驱动库编译 需要准备QT的源码Src,此次编译64位 在QTCreator中打开mysql.pro 修改两个pro 文件,下图为改好 1.mysql.pro TARGET = qsql ...
- 安卓记账本开发学习day2
今天遇到了xml文件报错,Wrong orientation? No orientation specified, and the default is horizontal, yet this la ...
- Java学习day37
动态语言:是一类在运行时可以改变其结构的语言:例如新的函数.对象.甚至代码可以被引进,已有的函数可以被删除或是其他结构上的变化. 主要动态语言:Objective-C.C#.JavaScript.PH ...
- 算法基础⑨搜索与图论--存在负权边的最短路--bellman_ford算法
bellman-ford算法 给定一个 n 个点 m 条边的有向图,图中可能存在重边和自环, 边权可能为负数. 请你求出从 1 号点到 n 号点的最多经过 k 条边的最短距离,如果无法从 1 号点走到 ...
- 【openstack】红帽公开课笔记内容openstack
overcloud节点自省失败(introspection) 节点自省--获取overcloud
- Redis为什么变慢了?透彻解读如何排查Redis性能问题
Redis 作为优秀的内存数据库,其拥有非常高的性能,单个实例的 OPS 能够达到 10W 左右.但也正因此如此,当我们在使用 Redis 时,如果发现操作延迟变大的情况,就会与我们的预期不符. 你也 ...