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)查询. 要求的是 ...
随机推荐
- 公共技术点之 Java 反射 Reflection
本文摘录地址: http://codekk.com/open-source-project-analysis/detail/Android/Mr.Simple/%E5%85%AC%E5%85%B1%E ...
- Shell +Cygwinterminal+WinMySQL 传参数授权
前言:新公司因为部分业务原因有好几百组win机器装MySQL授权登录比较麻烦,简单的写了一个shell传值自动授权的脚本,保存复用. #!/bin/bash #author liding@zlhy.c ...
- ubuntu 14 编译ARM g2o-20160424
1. 安装eigen sudo apt-get install libeigen3-dev sudo apt-get install libsuitesparse-dev sudo apt-get i ...
- Openssl genpkey命令
一.简介 genpkey命令用于产生各种密钥(RSA.DSA.DH.EC等)的私钥值. 二.语法 openssl genpkey [-out filename] [-outform PEM | DER ...
- python3--生成器并行运算
# Auther: Aaron Fan """def consumer(name): print("%s 准备吃包子啦!" % name) while ...
- hrabs的数据库session的修改
using System;using System.Data;using System.Collections;using System.Collections.Generic;using Syste ...
- float在内存中的存取方法
今天做了一些题目,想到float数据如何在内存中的形式.不知道一个浮点数是如何存成32位01字符串的.下面是查找的一些资料. 我们先通过java获取这些数的二进制表示. public class De ...
- 类操作,removeClass&addClass
// 添加类 function addClass(node,className){ var reg=new RegExp("\\b"+classNa ...
- LibreOJ 6000 搭配飞行员(最大流)
题解:最基础的最大流,按照主飞行员与起点建边,副飞行员与终点建边,可以同坐的主副飞行员之间建边,值均为一,然后跑一边最大流就完美了! 代码如下: #include<queue> #incl ...
- CSRF漏洞详细说明
CSRF漏洞详细说明 通常情况下,有三种方法被广泛用来防御CSRF攻击:验证token,验证HTTP请求的Referer,还有验证XMLHttpRequests里的自定义header.鉴于种种原因,这 ...