题目链接

题目大意:求序列内长度在$[L,R]$范围内前$k$大子序列之和。

----------------------

考略每个左端点$i$,合法的区间右端点在$[i+L,i+R]$内。

不妨暴力枚举所有左端点,找到以其为左端点满足条件的最大子序列。

用贪心的思想,这些序列一定是满足题意的。统计后将该序列删除。

但这样直接删除肯定会丢失一部分有用的序列。一些也在前$k$大范围内的序列可能跟删除部分有交集。

所以我们不妨设$maxi$指以$i$为左端点的子序列,以$maxi$为右端点时能取得最大值。从此处将原先的大区间$[i+L,i+R]$裂解成两个区间$[i+L,maxi-1]$和$[maxi+1,i+R]$。从这两个区间中再找较大的满足条件的序列。

维护显然用堆。设一个五元组$(v,i,l,r,w)$表示以$i$为左端点,右端点在$[i+L,i+R]$内时,能找出以$w$为右端点的最大值为$v$的子序列。以$v$作为关键字,建立大根堆维护即可。

最后一个问题就是查找。我们不妨预处理出前缀和,用前缀和查找子序列的和。最大值用$ST$表维护。

代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=;
int f[N][],pos[N][];
int n,k,l,r,op;
long long ans;
int maxn,maxi;
struct node
{
int v,i,l,r,w;
}t,tmp;
bool operator <(const node &a,const node &b)
{
return a.v<b.v;
}
priority_queue<node> q;
inline void RMQ(int l,int r)
{
int opt=log2(r-l+);
if (f[l][opt]>=f[r-(<<opt)+][opt]) maxn=f[l][opt],maxi=pos[l][opt];
else maxn=f[r-(<<opt)+][opt],maxi=pos[r-(<<opt)+][opt];
}
signed main()
{
memset(f,,sizeof(f));
f[][]=;
scanf("%lld%lld%lld%lld",&n,&k,&l,&r);
op=log2(n);
for (int i=;i<=n;i++)
{
scanf("%lld",&f[i][]);
pos[i][]=i;
f[i][]+=f[i-][];
}
for (int t=;t<=op;t++)
for (int i=;i<=n;i++) if (i+(<<(t-))->n) break;
else
{
if (f[i][t-]>=f[i+(<<(t-))][t-]) f[i][t]=f[i][t-],pos[i][t]=pos[i][t-];
else f[i][t]=f[i+(<<(t-))][t-],pos[i][t]=pos[i+(<<(t-))][t-];
}
for (int i=;i<=n-l+;i++)
{
RMQ(i+l-,i+min(n-i,r-));
t.v=maxn-f[i-][],t.i=i,t.l=i+l-,t.r=i+min(n-i,r-),t.w=maxi;
q.push(t);
}
while(k--)
{
t=q.top();
q.pop();
ans+=t.v;
if (t.w>t.l)
{
RMQ(t.l,t.w-);
tmp.v=maxn-f[t.i-][],tmp.i=t.i,tmp.l=t.l,tmp.r=t.w-,tmp.w=maxi;
q.push(tmp);
}
if (t.w<t.r)
{
RMQ(t.w+,t.r);
tmp.v=maxn-f[t.i-][],tmp.i=t.i,tmp.l=t.w+,tmp.r=t.r,tmp.w=maxi;
q.push(tmp);
}
}
printf("%lld",ans);
return ;
}

【NOI2010】超级钢琴 题解(贪心+堆+ST表)的更多相关文章

  1. BZOJ_2006_[NOI2010]超级钢琴_贪心+堆+ST表

    BZOJ_2006_[NOI2010]超级钢琴_贪心+堆+ST表 Description 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的 音乐 ...

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

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

  3. BZOJ2006:[NOI2010]超级钢琴——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=2006 https://www.luogu.org/problemnew/show/P2048#su ...

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

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

  5. [NOI2010] 超级钢琴 - 贪心,堆,ST表

    这也算是第K大问题的套路题了(虽然我一开始还想了个假算法),大体想法就是先弄出最优的一批解,然后每次从中提出一个最优解并转移到一个次优解,用优先队列维护这个过程即可. 类似的问题很多,放在序列上的,放 ...

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

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

  7. BZOJ 2006 NOI2010 超级钢琴 划分树+堆

    题目大意:给定一个序列.找到k个长度在[l,r]之间的序列.使得和最大 暴力O(n^2logn),肯定过不去 看到这题的第一眼我OTZ了一下午... 后来研究了非常久别人的题解才弄明确怎么回事...蒟 ...

  8. Bzoj 2006: [NOI2010]超级钢琴 堆,ST表

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

  9. [BZOJ2006][NOI2010]超级钢琴(ST表+堆)

    2006: [NOI2010]超级钢琴 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 3679  Solved: 1828[Submit][Statu ...

随机推荐

  1. C# DataTable与Excel读取与导出

    /// <summary> /// Excel->DataTable /// </summary> /// <param name="filePath&q ...

  2. 也来谈谈python编码

    一.coding:utf-8 让我们先来看一个示例,源码文件是utf-8格式: print('你好 python') 当使用python2执行该程序时会收到一下报错: File "./hel ...

  3. 互联网的寒冬下各大一线互联网公司还在用SpringBoot这是为什么?

    引言 现在各大技术社区 Spring Boot 的文章越来越多,Spring Boot 相关的图文.视频教程越来越多,使用 Spring Boot 的互联网公司也越来越多: Java 程序员现在出去面 ...

  4. Ethical Hacking - Web Penetration Testing(5)

    LOCAL FILE INCLUSION Allows an attacker to read ANY file on the same server. Access files outside ww ...

  5. Ethical Hacking - NETWORK PENETRATION TESTING(11)

    Securing your Network From the Above Attacks. Now that we know how to test the security of all known ...

  6. ssh配置、vscode使用及常用扩展

    1.ssh配置 1.1 进入命令行 win + r  > cmd 1.2 输入如下代码直接回车即可生成ssh  ssh-keygen -t rsa -C "xxx@qq.com&quo ...

  7. python读取hdfs并返回dataframe教程

    不多说,直接上代码 from hdfs import Client import pandas as pd HDFSHOST = "http://xxx:50070" FILENA ...

  8. JS闭包应用场景之函数回调(含函数的调用个人理解)

    首先我们来绑定一个函数给click事件,这个很好理解,就是创建一个匿名函数作为回调绑定给click事件,如下: 但如果我们想声明一个函数作为回调来绑定多个元素呢,例如下面(注意:绑定事件后不用加括号, ...

  9. 【线性表基础】基于线性表的简单算法【Java版】

    本文描述了基于线性表的简单算法及其代码[Java实现] 1-1 删除单链表中所有重复元素 // Example 1-1 删除单链表中所有重复元素 private static void removeR ...

  10. HTTP的实体数据

      数据类型表示实体数据的内容是什么,使用的是MIME    type,相关的头字段是Accept和Content-Type:  text:即文本格式的可读数据,我们最熟悉的应该就是text/html ...