Link:

https://www.lydsy.com/JudgeOnline/problem.php?id=2006

Algorithm:

对于此类区间最值类问题,我们可以通过控制一端不变来寻找当前点的最值,再综合比较

此题中,在求完前缀和后,在左端点确定的情况下,只要寻找前缀和最大的右端点

为了快速寻找最优的右端点位置,我们需要RMQ来进行维护

由于不存在修改操作而只有查询,那么ST List  O(1)查询 O(n)修改  的特性就能充分利用

在求出前缀和后用ST list维护区间MAX即可

定义一个四元组(i,L,R,pos),其中,i表示固定下的左端点,L,R表示右端点存在的区间,pos表示右端点此时最优位置

为了不涉及到ST list不支持的删除操作,在选定pos后四元组分为两段:

$(i,L,R,pos)−>(i,L,pos−1,pos′)+(i,pos+1,R,pos′′)$

这样用优先队列每次取出最优解即可

Code:

//by NewErA
#include<bits/stdc++.h> using namespace std;
typedef long long ll; inline int read()
{
char ch;int num,f=;
while(!isdigit(ch=getchar())) f|=(ch=='-');
num=ch-'';
while(isdigit(ch=getchar())) num=num*+ch-'';
return f?-num:num;
} struct SP
{
int i,l,r,pos;
}; const int MAXN=;
int n,k,L,R,a[MAXN],log_2[MAXN],st[MAXN][];
ll res=; void init()
{
log_2[]=;
for(int i=;i<=n;i++)
{
log_2[i]=log_2[i-];
if(<<(log_2[i]+)==i) log_2[i]++;
} for(int i=n;i>=;i--)
{
st[i][]=i;
for(int j=;(i+(<<j)-)<=n;j++)
if(a[st[i][j-]]>a[st[i+(<<(j-))][j-]]) st[i][j]=st[i][j-];
else st[i][j]=st[i+(<<(j-))][j-];
}
} int Query(int l,int r)
{
int x=log_2[r-l+];
if(a[st[l][x]]>a[st[r-(<<x)+][x]]) return st[l][x];
else return st[r-(<<x)+][x];
} inline bool operator < (SP x,SP y) //运算符重载
{
return a[x.pos]-a[x.i-]<a[y.pos]-a[y.i-];
} int main()
{
n=read();k=read();L=read();R=read();
for(int i=;i<=n;i++) a[i]=read();
for(int i=;i<=n;i++) a[i]+=a[i-]; init(); priority_queue<SP,vector<SP> > Q;
for(int i=;i<=n;i++)
if(i+L-<=n)
{
int t=min(i+R-,n);
Q.push(SP{i,i+L-,t,Query(i+L-,t)});
}
while(k--)
{
SP cur=Q.top();Q.pop();
res+=a[cur.pos]-a[cur.i-];
if(cur.pos->=cur.l) Q.push(SP{cur.i,cur.l,cur.pos-,Query(cur.l,cur.pos-)});
if(cur.pos+<=cur.r) Q.push(SP{cur.i,cur.pos+,cur.r,Query(cur.pos+,cur.r)});
}
cout << res;
return ;
}

1、priority_queue的运算符重载问题(Updating)

2、只需要RMQ的查询操作时尽量用ST List

3、如果删除1个或少量数据的操作难以实现时,考虑将原数据分段,递归式地考虑每一段的情况

[BZOJ 2006] 超级钢琴的更多相关文章

  1. BZOJ 2006 超级钢琴(划分树+优先队列)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2006 题意: 给出一个数列A,L,R,构造出一个新的集合,集合中的数字为A中任意连续t( ...

  2. bzoj 2006 超级钢琴 —— ST表

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2006 本来应该是可以用主席树,找区间最小值,取出来后再找那段区间的次小值...... 但也可 ...

  3. BZOJ 2006 超级钢琴(堆+主席树)

    很好的一道题. 题意:给出长度为n的数列,选择k个互不相同的区间,满足每个区间长度在[L,R]内,求所有选择的区间和的总和最大是多少.(n,k<=5e5). 首先将区间和转化为前缀和之差,那么我 ...

  4. [BZOJ 2006] [NOI 2010]超级钢琴(贪心+ST表+堆)

    [BZOJ 2006] [NOI 2010]超级钢琴(贪心+ST表+堆) 题面 给出一个长度为n的序列,选k段长度在L到R之间的区间,一个区间的值等于区间内所有元素之的和,使得k个区间的值之和最大.区 ...

  5. BZOJ 2006: [NOI2010]超级钢琴

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

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

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

  7. BZOJ 2006: [NOI2010]超级钢琴( RMQ + 堆 )

    取最大的K个, 用堆和RMQ来加速... ----------------------------------------------------------------- #include<c ...

  8. 【BZOJ 2006】2006: [NOI2010]超级钢琴(RMQ+优先队列)

    2006: [NOI2010]超级钢琴 Time Limit: 20 Sec  Memory Limit: 552 MBSubmit: 2792  Solved: 1388 Description 小 ...

  9. 2006: [NOI2010]超级钢琴 - BZOJ

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

随机推荐

  1. BZOJ day8

    好吧,, 补一天题解. 1001  狼抓兔子 妥妥的网络流啊,难度仅次于草地排水,边都给出来了.就是注意反向边也要有流量就行. 1007 水平可见直线 这个题按斜率排序(注意不是绝对值),然后将直线入 ...

  2. 兔子与兔子 [Hash]

    兔子与兔子 描述 很久很久以前,森林里住着一群兔子.有一天,兔子们想要研究自己的 DNA 序列.我们首先选取一个好长好长的 DNA 序列(小兔子是外星生物,DNA 序列可能包含 26 个小写英文字母) ...

  3. linux启动一个web项目时验证码不能出现的问题的解决

    解决方法: 在tomcatcatalina.sh中搜索cygwin=false,然后在它的上面加上这句话JAVA_OPTS='-Djava.awt.headless=true' 具体参考如下图片: 然 ...

  4. hadoop之HDFS与MapReduce

    Hadoop历史 雏形开始于2002年的Apache的Nutch,Nutch是一个开源Java 实现的搜索引擎.它提供了我们运行自己的搜索引擎所需的全部工具.包括全文搜索和Web爬虫. 随后在2003 ...

  5. windows 系统下git 的使用

    前言: 最新版本的git for windows也是有界面的,不再是以前的纯命令行操作,但是我习惯了乌龟,所以感觉还是直接用乌龟比较方便点~~ 前提,已安装以下: git for windows,未安 ...

  6. 关于IE6的一些总结

    开篇之前,循例简单说说IE6的一些背景吧. IE6是指微软浏览器系列中的第六个版本,它是在2001年的时候伴随着XP系统的问世而同时推出的一款浏览器.因为XP普及的原因,这款浏览器一度问鼎全球浏览器市 ...

  7. Python 进阶学习笔记

    把函数作为参数 import math def add(x, y, f): return f(x) + f(y) print add(, , math.sqrt) map(f, list) 函数 接收 ...

  8. swift中的尾随闭包的用法

    尾随闭包就是这个函数的最后一个参数是一个闭包,所以规定这个闭包既可以写在函数的参数括号里面,也可以直接放在最后面来使用,就像重新给这个函数定义了一次一样,有些怪,不过用的时候,可以把闭包写在外面的.这 ...

  9. mobius反演讲解

    mobius反演的基本形式为,假设知道函数F(x)=Σf(d) d|x,那么我们可以推出f(x)=Σmiu(d)*F(x/d) d|x,另一基本形式为假设知道函数F(x)=Σf(d) x|d,那么我们 ...

  10. Codeforces Round #469 Div. 2 A B C D E

    A. Left-handers, Right-handers and Ambidexters 题意 \(l\)个左撇子,\(r\)个右撇子,\(a\)个两手均可.要组成一支队伍,里面用左手的人数与用右 ...