这道题题号很清新啊!第一次开NOI的题,因为最近考到了这道题的升级版

我们先考虑\(O(n^2)\)大暴力,就是枚举前后端点然后开一个前缀和减一下即可。

然后引入正解,我们设一个三元组\(F(s,l,r)\)表示以\(s\)为左端点,右端点的范围在\([l,r]\)的时候最优的右端点为多少。

左端点确定了,右端点的区间也确定了,那么右端点的位置怎么求?

RMQ直接查询即可。由于要求值最大,因此我们RMQ出前缀和最大值即可

然后我们就可以得到一些三元组,考虑如何计算答案。

我们还是通过取最大值这点性质想到。因此我们用大根堆来维护,而要维护的东西应该就是这个区间的值了。

然后前缀和的作用就出来了。我们在比较时让键值为\(sum_t-sum_{s-1}\)即可。

当我们取出一个解时,注意以\(s\)为左端点的区间就不是没有用了,我们可以把它按选择的最优位置分裂成两半然后再扔回堆里为后续的做准备。

具体实现看CODE

#include<cstdio>
#include<cctype>
#include<queue>
using namespace std;
const int N=500005,P=25;
int n,k,l,r,sum[N],log[N];
long long ans;
struct data
{
int s,l,r,t;
bool operator <(const data x) const { return sum[x.t]-sum[x.s-1]>sum[t]-sum[s-1]; }
};
struct RMQ
{
int x,num;
}f[N][P];
priority_queue<data> big;
inline char tc(void)
{
static char fl[100000],*A=fl,*B=fl;
return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++;
}
inline void read(int &x)
{
x=0; char ch; int flag=1; while (!isdigit(ch=tc())) flag=ch^'-'?1:-1;
while (x=(x<<3)+(x<<1)+ch-'0',isdigit(ch=tc())); x*=flag;
}
inline int min(int a,int b)
{
return a<b?a:b;
}
inline void log_init(void)
{
for (register int i=2;i<=n;++i)
log[i]=log[i>>1]+1;
}
inline void RMQ_init(void)
{
for (register int j=1;j<P;++j)
for (register int i=1;i+(1<<j)-1<=n;++i)
f[i][j]=f[i][j-1].x>f[i+(1<<j-1)][j-1].x?f[i][j-1]:f[i+(1<<j-1)][j-1];
}
inline int query(int l,int r)
{
int k=log[r-l+1];
return f[l][k].x>f[r-(1<<k)+1][k].x?f[l][k].num:f[r-(1<<k)+1][k].num;
}
int main()
{
//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
register int i; read(n); read(k); read(l); read(r);
for (i=1;i<=n;++i)
read(sum[i]),sum[i]+=sum[i-1],f[i][0]=((RMQ){sum[i],i});
log_init(); RMQ_init();
for (i=1;i<=n;++i)
if (i+l-1<=n) big.push((data){i,i+l-1,min(n,i+r-1),query(i+l-1,min(n,i+r-1))});
while (k--)
{
data now=big.top(); big.pop(); ans+=sum[now.t]-sum[now.s-1];
if (now.l^now.t) big.push((data){now.s,now.l,now.t-1,query(now.l,now.t-1)});
if (now.r^now.t) big.push((data){now.s,now.t+1,now.r,query(now.t+1,now.r)});
}
return printf("%lld",ans),0;
}

Luogu 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. P2048 [NOI2010]超级钢琴 (RMQ,堆)

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

  9. P2048 [NOI2010]超级钢琴

    传送门 考虑维护前缀和 $sum[i]$ 那么对于每一个位置 $i$ ,左端点为 $i$ 右端点在 $[i+L-1,i+R-1]$ 区间的区间最大值容易维护 维护三元组 $(o,l,r)$ ,表示左端 ...

随机推荐

  1. Linux Linux内核参数调优

    Linux内核参数调优 by:授客 QQ:1033553122 关于调优的建议: 1.出错时,可以查看操作系统日志,可能会找到一些有用的信息 2.尽量不要“批量”修改内核参数,笔者就曾这么干过,结果“ ...

  2. Spring 事件

    JDK事件 java通过java.util.EventObject类和java.util.EventListener接口描述事件和监听器 事件源,事件的产生者,任何一个EventObject都必须拥有 ...

  3. Python笔记(十四):操作excel openpyxl模块

    (一)  常遇到的情况 就我自己来说,常遇到的情况可能就下面几种: 读取excel整个sheet页的数据. 读取指定行.列的数据 往一个空白的excel文档写数据 往一个已经有数据的excel文档追加 ...

  4. HDU ACM 3790 最短路径问题

    最短路径问题 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Subm ...

  5. nginx 编译安装时的编译参数说明(不建议看)

    https://www.cnblogs.com/wazy/p/8108824.html ./configure --user=www \ #worker进程运行用户 --group=www \ #wo ...

  6. Html引入百度富文本编辑器ueditor

    在日常工作用,肯定有用到富文本编辑器的时候,富文本编辑器功能强大使用方便,我用的是百度富文本编辑器,首先需要下载好百度编辑器的demo, 然后创建ueditor.html文件,引入百度编辑器,然后在h ...

  7. cf C. Finite or not? 数论

    You are given several queries. Each query consists of three integers pp, qq and bb. You need to answ ...

  8. JS操作DOM节点大全

    1.Javascript删除节点 在Javascript中,只提供了一种删除节点的方法:removeChild(). removeChild() 方法用来删除父节点的一个子节点. 语法:parent. ...

  9. PHP的curl查看header信息的功能(包括查看返回header和请求header)

    PHP的curl功能十分强大,简单点说,就是一个PHP实现浏览器的基础. 最常用的可能就是抓取远程数据或者向远程POST数据.但是在这个过程中,调试时,可能会有查看header的必要. 如下: ech ...

  10. MySQL性能分析工具之PROFILE

    Mysql Profile 如何开启Profiles功能以及如何简单使用: https://www.cnblogs.com/zengkefu/p/6519010.html MySQL profiles ...