传送门

考虑维护前缀和 $sum[i]$

那么对于每一个位置 $i$ ,左端点为 $i$ 右端点在 $[i+L-1,i+R-1]$ 区间的区间最大值容易维护

维护三元组 $(o,l,r)$ ,表示左端点为 $o$ ,右端点 $\in [l,r]$ 的区间最大值,然后把它扔到一个堆里,每次弹出最大值计算贡献

计算完后,设此三元组右端点为 $t$,还要记得把 $(o,l,t-1)$,和 $(o,t+1,r)$ 扔到堆里

具体看代码,不难理解

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
using namespace std;
typedef long long ll;
inline int read()
{
int x=,f=; char ch=getchar();
while(ch<''||ch>'') { if(ch=='-') f=-; ch=getchar(); }
while(ch>=''&&ch<='') { x=(x<<)+(x<<)+(ch^); ch=getchar(); }
return x*f;
}
const int N=1e6+;
int n,K;
int sum[N],f[N][],Log[N];
namespace ST {//维护sum区间最大值的位置
void init()
{
for(int i=;i<=n;i++) f[i][]=i;
Log[]=-; for(int i=;i<=n;i++) Log[i]=Log[i>>]+;
for(int k=;(<<k)<=n;k++)
for(int i=;i+(<<k-)<=n;i++)
{
if(sum[f[i][k-]]>sum[ f[ i+(<<k-) ][k-] ]) f[i][k]=f[i][k-];
else f[i][k]=f[ i+(<<k-) ][k-];
}
}
inline int query(int l,int r)
{
int k=Log[r-l+];
if(sum[ f[l][k] ]>sum[ f[r-(<<k)+][k] ]) return f[l][k];
return f[r-(<<k)+][k];
}
}
struct dat {
int o,l,r,t;
dat (int o,int l,int r) : o(o),l(l),r(r),t(ST::query(l,r)) {}
inline bool operator < (const dat &tmp) const {
return sum[t]-sum[o-]<sum[tmp.t]-sum[tmp.o-];
}
};
priority_queue <dat> Q;
ll ans;
int main()
{
n=read(),K=read(); int l=read(),r=read(),a;
for(int i=;i<=n;i++) a=read(),sum[i]=sum[i-]+a;
ST::init();
for(int i=;i<=n;i++)
if(i+l-<=n) Q.push( dat(i,i+l-,min(n,i+r-)) );
while(K--)
{
dat T=Q.top(); Q.pop(); ans+=(sum[T.t]-sum[T.o-]);
if(T.l<T.t) Q.push(dat(T.o,T.l,T.t-));
if(T.r>T.t) Q.push(dat(T.o,T.t+,T.r));
}
printf("%lld",ans);
return ;
}

P2048 [NOI2010]超级钢琴的更多相关文章

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

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

  2. 洛谷 P2048 [NOI2010]超级钢琴 解题报告

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

  3. 【题解】P2048 [NOI2010]超级钢琴

    [题解][P2048 NOI2010]超级钢琴 一道非常套路的题目.是堆的套路题. 考虑前缀和,我们要是确定了左端点,就只需要在右端区间查询最大的那个加进来就好了.\(sum_j-sum_{i-1}​ ...

  4. [洛谷P2048] [NOI2010] 超级钢琴

    洛谷题目链接:[NOI2010]超级钢琴 题目描述 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的音乐. 这架超级钢琴可以弹奏出n个音符,编号 ...

  5. LGOJ P2048 [NOI2010]超级钢琴

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

  6. 洛谷 P2048 [NOI2010]超级钢琴 || Fantasy

    https://www.luogu.org/problemnew/show/P2048 http://www.lydsy.com/JudgeOnline/problem.php?id=2006 首先计 ...

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

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

  8. Luogu P2048 [NOI2010]超级钢琴

    这道题题号很清新啊!第一次开NOI的题,因为最近考到了这道题的升级版. 我们先考虑\(O(n^2)\)大暴力,就是枚举前后端点然后开一个前缀和减一下即可. 然后引入正解,我们设一个三元组\(F(s,l ...

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

    大意: 给定n元素序列a, 定义一个区间的权值为区间内所有元素和, 求前k大的长度在[L,R]范围内的区间的权值和. 固定右端点, 转为查询左端点最小的前缀和, 可以用RMQ O(1)查询. 要求的是 ...

随机推荐

  1. js 线程和进程的关系

    进程(process)和线程(thread)是操作系统的基本概念 1.计算机的核心是CPU,它承担了所有的计算任务 2.单个CPU一次只能运行一个任务 3.进程它代表CPU所能处理的单个任务.任一时刻 ...

  2. - description 方法作用

    自定义一个Person类 @interface Person : NSObject { int _age; double _height; double _weight; NSString *_nam ...

  3. 633. Sum of Square Numbers 是否由两个完全平方数构成

    [抄题]: Given a non-negative integer c, your task is to decide whether there're two integers a and b s ...

  4. Python学习笔记_Python向Excel写入数据

    实验环境 1.OS:Win 10 64位 2.Python 3.7 3.如果没有安装xlwt库,则安装:pip install xlwt 下面是从网上找到的一段代码,网上这段代码,看首行注释行,是在L ...

  5. java面试题 级hr解答 非技术问题 !=!=未看

    Java基础 ● 集合类以及集合框架:HashMap与HashTable实现原理,线程安全性,hash冲突及处理算法:ConcurrentHashMap: ● 进程和线程的区别: ● Java的并发. ...

  6. c语言学习笔记 switch case语句为什么要加break

    先来看一个没有break的例子: int main() { int a = 1; switch (a) { case 1: printf("1"); case 2: printf( ...

  7. Part10-C语言环境初始化-C与汇编混合编程lesson4

    1.为什么要混合编程 汇编语言:执行效率高:编写繁琐: 执行效率高:能够更直接地控制处理器. c语言:可读性强,移植性好,调试方便. 1.汇编调用c函数 2.c调用汇编函数 汇编语言定义的函数(标号) ...

  8. javascript中把一个数组的内容全部赋值给另外一个数组

    如:var a = [1,2,3,4];var b= [];b = a;这个不是把值赋值过去而是b作为a的引用,b改变的是a如何b指向的是一个新数组,a把元素值全部赋值过去? 1.普通数组可以使用   ...

  9. 黑盒测试实践-任务进度-Day03

    任务进度11-28 使用工具 selenium 小组成员 华同学.郭同学.穆同学.沈同学.覃同学.刘同学 任务进度 经过了前两天的学习任务的安排,以下是大家的任务进度: 华同学(任务1) 1.今天就接 ...

  10. Java Thread.join()详解--父线程等待子线程结束后再结束

    目录(?)[+] 阅读目录 一.使用方式. 二.为什么要用join()方法 三.join方法的作用 join 四.用实例来理解 打印结果: 打印结果: 五.从源码看join()方法   join是Th ...