题目描述

小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的音乐。 这架超级钢琴可以弹奏出n个音符,编号为1至n。第i个音符的美妙度为Ai,其中Ai可正可负。 一个“超级和弦”由若干个编号连续的音符组成,包含的音符个数不少于L且不多于R。我们定义超级和弦的美妙度为其包含的所有音符的美妙度之和。两个超级和弦被认为是相同的,当且仅当这两个超级和弦所包含的音符集合是相同的。 小Z决定创作一首由k个超级和弦组成的乐曲,为了使得乐曲更加动听,小Z要求该乐曲由k个不同的超级和弦组成。我们定义一首乐曲的美妙度为其所包含的所有超级和弦的美妙度之和。小Z想知道他能够创作出来的乐曲美妙度最大值是多少。

输入

第一行包含四个正整数n, k, L, R。其中n为音符的个数,k为乐曲所包含的超级和弦个数,L和R分别是超级和弦所包含音符个数的下限和上限。 接下来n行,每行包含一个整数Ai,表示按编号从小到大每个音符的美妙度。
N<=500,000  k<=500,000  -1000<=Ai<=1000,1<=L<=R<=N且保证一定存在满足条件的乐曲

输出

只有一个整数,表示乐曲美妙度的最大值。

样例输入

4 3 2 3
3
2
-6
8

样例输出

11


题解

倍增RMQ(貌似这个叫做ST表)+STL-堆

首先我们将连续子序列和转化为前缀和相减,那么对于每个左端点,找它的右端点,就转变为求某范围内前缀和的最大值、次大值、...

但是直接拿出整个序列显然会TLE+MLE。

我们考虑,如果左端点t,右端点[l,r],我们找出属于[l,r]的位置p,使得sum[p]最大。那么很显然,当且仅当p被选择之后,[l,p-1]和[p+1,r]内的右端点才可能会被选择。

所以我们可以维护一个结构体,储存t、l、r、p、v,分别表示左端点、右端点区间的左位置、右端点区间的右位置、右端点区间最大值的位置、右端点区间最大值,显然v=sum[p]-sum[t-1]。我们优先选择v较大的区间把它拿出来,把它的v加入到答案中。然后考虑剩下的[l,p-1]和[p+1,r],如果存在这些区间的话,采取相同的方式处理即可。这个过程显然可以使用堆来维护。

维护区间最大值即位置。可以使用倍增RMQ来解决,时间复杂度更低一些。

因此总的时间复杂度为$O((n+k)\log n)$

另外需要注意的是priority_queue需要重载<运算符,而不是>(尽管它是大根堆)

#include <cstdio>
#include <queue>
#define N 500010
using namespace std;
struct data
{
int t , b , e , v , p;
data() {}
data(int t0 , int b0 , int e0 , int v0 , int p0) {t = t0 , b = b0 , e = e0 , v = v0 , p = p0;}
bool operator<(const data a)const {return v < a.v;}
}tmp;
priority_queue<data> q;
int sum[N] , maxn[N][20] , maxp[N][20] , log[N];
int getmaxn(int x , int y)
{
int k = log[y - x + 1];
return max(maxn[x][k] , maxn[y - (1 << k) + 1][k]);
}
int getmaxp(int x , int y)
{
int k = log[y - x + 1];
return maxn[x][k] > maxn[y - (1 << k) + 1][k] ? maxp[x][k] : maxp[y - (1 << k) + 1][k];
}
int main()
{
int n , k , l , r , i , j , x , y;
long long ans = 0;
scanf("%d%d%d%d" , &n , &k , &l , &r);
for(i = 1 ; i <= n ; i ++ ) scanf("%d" , &x) , sum[i] = sum[i - 1] + x , maxn[i][0] = sum[i] , maxp[i][0] = i;
for(i = 2 ; i <= n ; i ++ ) log[i] = log[i >> 1] + 1;
for(i = 1 ; i <= log[n] ; i ++ )
{
for(j = 1 ; j <= n - (1 << i) + 1 ; j ++ )
{
if(maxn[j][i - 1] > maxn[j + (1 << (i - 1))][i - 1]) maxn[j][i] = maxn[j][i - 1] , maxp[j][i] = maxp[j][i - 1];
else maxn[j][i] = maxn[j + (1 << (i - 1))][i - 1] , maxp[j][i] = maxp[j + (1 << (i - 1))][i - 1];
}
}
for(i = 1 ; i <= n - l + 1 ; i ++ ) x = i + l - 1 , y = min(i + r - 1 , n) , q.push(data(i , x , y , getmaxn(x , y) - sum[i - 1] , getmaxp(x , y)));
while(k -- )
{
tmp = q.top() , q.pop() , ans += tmp.v;
if(tmp.p > tmp.b) x = tmp.b , y = tmp.p - 1 , q.push(data(tmp.t , x , y , getmaxn(x , y) - sum[tmp.t - 1] , getmaxp(x , y)));
if(tmp.p < tmp.e) x = tmp.p + 1 , y = tmp.e , q.push(data(tmp.t , x , y , getmaxn(x , y) - sum[tmp.t - 1] , getmaxp(x , y)));
}
printf("%lld\n" , ans);
return 0;
}

【bzoj2006】[NOI2010]超级钢琴 倍增RMQ+STL-堆的更多相关文章

  1. [NOI2010]超级钢琴 倍增

    [NOI2010]超级钢琴 倍增 题面 暴力:枚举区间丢入堆\(O(n^2logn)\) 正解:考虑每次枚举和弦起点\(s\),那么以\(s\)为起点的和弦为\(sum[t]-sum[s](s+L-1 ...

  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 2006】2006: [NOI2010]超级钢琴(RMQ+优先队列)

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

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

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

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

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

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

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

随机推荐

  1. JAVA | 学生选课系统

    这里使用JAVA语言编写的简易的学生选课系统,展现的都是这个系统核心代码. 其中有不足欢迎批评和指正! 链接数据库的代码 package connection;//连接数据库student impor ...

  2. MySql学习笔记06

    课程回顾 一对一关联 案例1:查询每个员工的名字和主管领导的名字 select e.ename 员工姓名,m.ename 领导姓名 from emp e join emp m on e.mgr=m.e ...

  3. Java OOP——第四章 异常

    1. 接口:接口就是给出一些没有内容的方法,封装到一起,到某个类要使用的时候,在根据具体情况把这些方法写出来. 接口是更加抽象的抽象的类, 抽象类里的方法可以有方法体, 接口里的所有方法都没有方法体. ...

  4. 【nat---basic,napt,easy ip】

    display nat :显示nat 信息 debugging nat :对nat进行调试 reset nat session:擦除nat连接配置 basic-nat:公网->私网(一对一) n ...

  5. ES6--Set之再理解

    Set 其实2016年就看过阮大神的ECMAScript 6 入门,当时看了Set之后,大致看懂了,但事实上根本没有理解Set到底是什么,所以更记不住,平时做项目大多用到的还是ES5的传统写法,以至于 ...

  6. 从0开始 java 网站开发(jsp)【1】

    前提:安装java 并配置环境变量 java下载地址: http://www.java.com/zh_CN/ 环境变量配置 本地PC路径: 电脑--属性--高级--环境变量 在系统变量中: 新建 名: ...

  7. java第二章 变量和运算符

      Java 基础应用编程——  变量和运算符 1.Java程序结构          数据类型:确定要存储在内存中的数据的类型.          变量:是存储数据的基本单元 2.变量的概念   变 ...

  8. Centos7下lamp环境搭建的小笔记

    刚刚把校赛弄完,赛前在环境搭建上花了蛮多时间,也正好记一下笔记 0.首先更新源 清华大学开源镜像站的源 https://mirrors.tuna.tsinghua.edu.cn/help/centos ...

  9. 3124: [Sdoi2013]直径

    3124: [Sdoi2013]直径 https://www.lydsy.com/JudgeOnline/problem.php?id=3124 分析: 所有直径都经过的边,一定都是连续的一段.(画个 ...

  10. 【APUE】Chapter15 Interprocess Communication

    15.1 Introduction 这部分太多概念我不了解.只看懂了最后一段,进程间通信(IPC)内容被组织成了三个部分: (1)classical IPC : pipes, FIFOs, messa ...