BZOJ2006:[NOI2010]超级钢琴
浅谈\(RMQ\):https://www.cnblogs.com/AKMer/p/10128219.html
题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=2006
首先,序列\([l,r]\)的和可以转化成前缀和相减:\(sum[r]-sum[l-1]\)。
其次,对于每个右端点\(pos\),有效左端点都是一段区间\([pos-r,pos-l]\)。而这里面前缀和最小的则是最优左端点。
一开始我们将所有的四元组\((v,pos,l,r)\)丢到大根堆里。这个四元组表示以\(pos\)为右端点,有效左端点区间在\([l,r]\)内,最大值为\(v\)。假设最优左端点是\(pos'\),那么对于最优解,我们只需要执行如下步骤\(k\)次即可:
取出堆顶,\(ans+=v\)。
将\((sum[pos]-query(l,pos'-1),pos,l,pos'-1)\)与\((sum[pos]-query(pos'+1,r),pos,pos'+1,r)\)放回堆里。这样可以保证\([pos',pos]\)不会再被取出。
\(query(l,r)\)表示求区间\([l,r]\)的前缀和最小值。这样,问题就得到了完美解决。
时间复杂度:\(O(nlogn)\)
空间复杂度:\(O(nlogn)\)
代码如下:
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn=5e5+5;
ll ans;
int n,limit,L,R;
int a[maxn],Log[maxn],f[20][maxn];
int read() {
int x=0,f=1;char ch=getchar();
for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
return x*f;
}
struct node {
int v,pos,l,r;
node() {}
node(int _v,int _pos,int _l,int _r) {
v=_v,pos=_pos,l=_l,r=_r;
}
bool operator<(const node &a)const {
return v<a.v;
}
};
struct Heap {
int tot;
node tree[maxn<<1];
void ins(node a) {
tree[++tot]=a;
int pos=tot;
while(pos>1) {
if(tree[pos>>1]<tree[pos])
swap(tree[pos>>1],tree[pos]),pos>>=1;
else break;
}
}
node pop() {
node res=tree[1];
tree[1]=tree[tot--];
int pos=1,son=2;
while(son<=tot) {
if(son<tot&&tree[son]<tree[son|1])son|=1;
if(tree[pos]<tree[son])
swap(tree[pos],tree[son]),pos=son,son=pos<<1;
else break;
}
return res;
}
}T;//手写堆carry你进第一版,值得拥有!
int fake(int num1,int num2) {
if(a[num1]<a[num2])return num1;
return num2;
}
int query(int l,int r) {
int x=Log[r-l+1];
return fake(f[x][l],f[x][r-(1<<x)+1]);
}
int main() {
n=read(),limit=read();
L=read(),R=read();Log[0]=-1;
for(int i=1;i<=n;i++) {
f[0][i]=i;
Log[i]=Log[i>>1]+1;
a[i]=read()+a[i-1];
}
for(int i=1;i<=19;i++)
for(int j=0;j+(1<<i)-1<=n;j++)
f[i][j]=fake(f[i-1][j],f[i-1][j+(1<<(i-1))]);
for(int i=L;i<=n;i++) {
int l=max(0,i-R),r=i-L;
T.ins(node(a[i]-a[query(l,r)],i,l,r));
}
for(int i=1;i<=limit;i++) {
node tmp=T.pop();
ans+=tmp.v;
int pos=query(tmp.l,tmp.r);
if(pos-1>=tmp.l)
T.ins(node(a[tmp.pos]-a[query(tmp.l,pos-1)],tmp.pos,tmp.l,pos-1));
if(pos+1<=tmp.r)
T.ins(node(a[tmp.pos]-a[query(pos+1,tmp.r)],tmp.pos,pos+1,tmp.r));
}
printf("%lld\n",ans);
return 0;
}
BZOJ2006:[NOI2010]超级钢琴的更多相关文章
- bzoj2006 [NOI2010]超级钢琴 (及其拓展)
bzoj2006 [NOI2010]超级钢琴 给定一个序列,求长度在 \([L,\ R]\) 之间的区间和的前 \(k\) 大之和 \(n\leq5\times10^5,\ k\leq2\times1 ...
- bzoj千题计划162:bzoj2006: [NOI2010]超级钢琴
http://www.lydsy.com/JudgeOnline/problem.php?id=2006 输出最大的k个 sum[r]-sum[l-1] (L<=r-l+1<=R) 之和 ...
- BZOJ2006 [NOI2010]超级钢琴 【堆 + RMQ】
2006: [NOI2010]超级钢琴 Time Limit: 20 Sec Memory Limit: 552 MB Submit: 3446 Solved: 1692 [Submit][Sta ...
- [BZOJ2006][NOI2010]超级钢琴(ST表+堆)
2006: [NOI2010]超级钢琴 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 3679 Solved: 1828[Submit][Statu ...
- [BZOJ2006] [NOI2010]超级钢琴 主席树+贪心+优先队列
2006: [NOI2010]超级钢琴 Time Limit: 20 Sec Memory Limit: 552 MBSubmit: 3591 Solved: 1780[Submit][Statu ...
- bzoj2006 noi2010 超级钢琴 主席树 + 优先队列
Time Limit: 20 Sec Memory Limit: 552 MBSubmit: 2435 Solved: 1195 Description 小 Z是一个小有名气的钢琴家,最近C博士送 ...
- BZOJ2006[NOI2010]超级钢琴——堆+主席树
题目描述 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的 音乐. 这架超级钢琴可以弹奏出n个音符,编号为1至n.第i个音符的美妙度为Ai,其中 ...
- 【贪心 计数】bzoj2006: [NOI2010]超级钢琴
这么经典的贪心我怎么现在才做啊…… Description 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的 音乐. 这架超级钢琴可以弹奏出n个 ...
- BZOJ2006——[NOI2010]超级钢琴
1.题意:给一个序列,让你取出k个不同的区间,要求长度在之间,问所有区间和的最大值 2.分析:这道题拿过来就能知道是要拿出前k个最大的区间,我们思考最暴力的做法,就是把这个所有的区间枚举出来算,取出前 ...
- bzoj2006: [NOI2010]超级钢琴
题意:给一个序列(n<=500000),要求选定k个不同区间,使得区间长度在L,R之间,并使得k个区间和之和最大,输出这个最大值. 刚拿到题的时候想的是,对于每个点,如果以它开头,那么之后的L- ...
随机推荐
- <LeetCode OJ> 141 / 142 Linked List Cycle(I / II)
Given a linked list, determine if it has a cycle in it. Follow up: Can you solve it without using ex ...
- Jest — ElasticSearch Java 客户端
1. 介绍 任何使用过Elasticsearch的人都知道,使用基于rest的搜索API构建查询可能是单调乏味且容易出错的. 在本教程中,我们将研究Jest,一个用于Elasticsearch的HTT ...
- ReactNative Navigator
https://facebook.github.io/react-native/docs/navigator.html Navigator实现了页面之间的跳转. Demo描述:打开即进入“课程”页面, ...
- Python模拟登录12306
#!/usr/bin/python # -*- coding: utf-8 -*- import re; import sys; import cookielib; import urllib; im ...
- 【C语言】一句printf代码——{ a[0] ? 0[a] }
这是前段时间做的http://fun.coolshell.cn/中的一道题,很有意思,涉及的其实是C的基础,不过当时第一次看见这行代码确实把我弄懵了: printf(&unix["\ ...
- win10 64位 安装TensorFlow
.由于之前安装的是python2.7 ,tensorflow在windows下必须要python3 网上查了一下有三种方法2版本共存 1.不用Anaconda windows 安装python2 与p ...
- python 中读取excel
第一步: 先下载一个xlrd 包 # pip install xlrd import xlrd from datetime import date, datetime file = '学生信息表.x ...
- windows下的常用命令
net start ... 启动某个服务 net stop ... 停止某个服务 net start 查看所有启动的服务 services.msc 打开服务的界面 ipconfig ...
- dubbo介绍及其使用案例
dubbo介绍及其使用案例 1. Dubbo是什么? Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案.简单的说,dubbo就是个服务框架,如果 ...
- 远程服务器上的weblogic项目管理(三)常用指令及常见错误
weblogic的管理流程已在前两节整理完毕,接下来汇总一下linux环境下的weblogic管理常用指令及常见错误: 常用指令: ./startWebLogic.sh 启动weblogic ./st ...