P2048 [NOI2010]超级钢琴
考虑维护前缀和 $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]超级钢琴的更多相关文章
- P2048 [NOI2010]超级钢琴(RMQ+堆+贪心)
P2048 [NOI2010]超级钢琴 区间和--->前缀和做差 多次查询区间和最大--->前缀和RMQ 每次取出最大的区间和--->堆 于是我们设个3元组$(o,l,r)$,表示左 ...
- 洛谷 P2048 [NOI2010]超级钢琴 解题报告
P2048 [NOI2010]超级钢琴 题目描述 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的音乐. 这架超级钢琴可以弹奏出n个音符,编号为 ...
- 【题解】P2048 [NOI2010]超级钢琴
[题解][P2048 NOI2010]超级钢琴 一道非常套路的题目.是堆的套路题. 考虑前缀和,我们要是确定了左端点,就只需要在右端区间查询最大的那个加进来就好了.\(sum_j-sum_{i-1} ...
- [洛谷P2048] [NOI2010] 超级钢琴
洛谷题目链接:[NOI2010]超级钢琴 题目描述 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的音乐. 这架超级钢琴可以弹奏出n个音符,编号 ...
- LGOJ P2048 [NOI2010]超级钢琴
题目描述 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的音乐. 这架超级钢琴可以弹奏出n个音符,编号为1至n.第i个音符的美妙度为Ai,其中A ...
- 洛谷 P2048 [NOI2010]超级钢琴 || Fantasy
https://www.luogu.org/problemnew/show/P2048 http://www.lydsy.com/JudgeOnline/problem.php?id=2006 首先计 ...
- 洛谷P2048 [NOI2010]超级钢琴 题解
2019/11/14 更新日志: 近期发现这篇题解有点烂,更新一下,删繁就简,详细重点.代码多加了注释.就酱紫啦! 正解步骤 我们需要先算美妙度的前缀和,并初始化RMQ. 循环 \(i\) 从 \(1 ...
- Luogu P2048 [NOI2010]超级钢琴
这道题题号很清新啊!第一次开NOI的题,因为最近考到了这道题的升级版. 我们先考虑\(O(n^2)\)大暴力,就是枚举前后端点然后开一个前缀和减一下即可. 然后引入正解,我们设一个三元组\(F(s,l ...
- P2048 [NOI2010]超级钢琴 (RMQ,堆)
大意: 给定n元素序列a, 定义一个区间的权值为区间内所有元素和, 求前k大的长度在[L,R]范围内的区间的权值和. 固定右端点, 转为查询左端点最小的前缀和, 可以用RMQ O(1)查询. 要求的是 ...
随机推荐
- js 线程和进程的关系
进程(process)和线程(thread)是操作系统的基本概念 1.计算机的核心是CPU,它承担了所有的计算任务 2.单个CPU一次只能运行一个任务 3.进程它代表CPU所能处理的单个任务.任一时刻 ...
- - description 方法作用
自定义一个Person类 @interface Person : NSObject { int _age; double _height; double _weight; NSString *_nam ...
- 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 ...
- Python学习笔记_Python向Excel写入数据
实验环境 1.OS:Win 10 64位 2.Python 3.7 3.如果没有安装xlwt库,则安装:pip install xlwt 下面是从网上找到的一段代码,网上这段代码,看首行注释行,是在L ...
- java面试题 级hr解答 非技术问题 !=!=未看
Java基础 ● 集合类以及集合框架:HashMap与HashTable实现原理,线程安全性,hash冲突及处理算法:ConcurrentHashMap: ● 进程和线程的区别: ● Java的并发. ...
- c语言学习笔记 switch case语句为什么要加break
先来看一个没有break的例子: int main() { int a = 1; switch (a) { case 1: printf("1"); case 2: printf( ...
- Part10-C语言环境初始化-C与汇编混合编程lesson4
1.为什么要混合编程 汇编语言:执行效率高:编写繁琐: 执行效率高:能够更直接地控制处理器. c语言:可读性强,移植性好,调试方便. 1.汇编调用c函数 2.c调用汇编函数 汇编语言定义的函数(标号) ...
- javascript中把一个数组的内容全部赋值给另外一个数组
如:var a = [1,2,3,4];var b= [];b = a;这个不是把值赋值过去而是b作为a的引用,b改变的是a如何b指向的是一个新数组,a把元素值全部赋值过去? 1.普通数组可以使用 ...
- 黑盒测试实践-任务进度-Day03
任务进度11-28 使用工具 selenium 小组成员 华同学.郭同学.穆同学.沈同学.覃同学.刘同学 任务进度 经过了前两天的学习任务的安排,以下是大家的任务进度: 华同学(任务1) 1.今天就接 ...
- Java Thread.join()详解--父线程等待子线程结束后再结束
目录(?)[+] 阅读目录 一.使用方式. 二.为什么要用join()方法 三.join方法的作用 join 四.用实例来理解 打印结果: 打印结果: 五.从源码看join()方法 join是Th ...