浅谈\(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]超级钢琴的更多相关文章

  1. bzoj2006 [NOI2010]超级钢琴 (及其拓展)

    bzoj2006 [NOI2010]超级钢琴 给定一个序列,求长度在 \([L,\ R]\) 之间的区间和的前 \(k\) 大之和 \(n\leq5\times10^5,\ k\leq2\times1 ...

  2. bzoj千题计划162:bzoj2006: [NOI2010]超级钢琴

    http://www.lydsy.com/JudgeOnline/problem.php?id=2006 输出最大的k个 sum[r]-sum[l-1] (L<=r-l+1<=R) 之和 ...

  3. BZOJ2006 [NOI2010]超级钢琴 【堆 + RMQ】

    2006: [NOI2010]超级钢琴 Time Limit: 20 Sec  Memory Limit: 552 MB Submit: 3446  Solved: 1692 [Submit][Sta ...

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

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

  5. [BZOJ2006] [NOI2010]超级钢琴 主席树+贪心+优先队列

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

  6. bzoj2006 noi2010 超级钢琴 主席树 + 优先队列

    Time Limit: 20 Sec  Memory Limit: 552 MBSubmit: 2435  Solved: 1195 Description 小 Z是一个小有名气的钢琴家,最近C博士送 ...

  7. BZOJ2006[NOI2010]超级钢琴——堆+主席树

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

  8. 【贪心 计数】bzoj2006: [NOI2010]超级钢琴

    这么经典的贪心我怎么现在才做啊…… Description 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的 音乐. 这架超级钢琴可以弹奏出n个 ...

  9. BZOJ2006——[NOI2010]超级钢琴

    1.题意:给一个序列,让你取出k个不同的区间,要求长度在之间,问所有区间和的最大值 2.分析:这道题拿过来就能知道是要拿出前k个最大的区间,我们思考最暴力的做法,就是把这个所有的区间枚举出来算,取出前 ...

  10. bzoj2006: [NOI2010]超级钢琴

    题意:给一个序列(n<=500000),要求选定k个不同区间,使得区间长度在L,R之间,并使得k个区间和之和最大,输出这个最大值. 刚拿到题的时候想的是,对于每个点,如果以它开头,那么之后的L- ...

随机推荐

  1. 卡特兰数-Catalan数

    卡特兰数的含义: 说到卡特兰数,就不得不提及卡特兰数序列.卡特兰数序列是一个整数序列.其通项公式是我们从中取出的就叫做第n个卡特兰数数,前几个卡特兰数数是:1, 1, 2, 5, 14, 42, 13 ...

  2. 1-1:CSS3课程入门之属性选择器

    div[name=jewave] 选取属性名为name且属性值是"jewave"的元素 div[name^=jewave]选取属性名为name且属性值以"jewave&q ...

  3. python实现接口测试到unittest框架集成

    接口测试是面试测试岗位基本都会问到的问题,但是对于一些刚做测试的小伙伴可能并不是很熟悉,也有可能了解接口测试,但是完全不知道接口自动化怎么做.下面我们大概介绍一下. 首先我们需要知道接口自动化测试的目 ...

  4. erlang中遍历取出某个位置的最大值

    例:有这么一个列表,A = [["abc","bds",3],["ssdss","dddx",2],["sfa ...

  5. Spring cloud微服务实战——基于OAUTH2.0统一认证授权的微服务基础架构

    https://blog.csdn.net/w1054993544/article/details/78932614

  6. CPI和GDP有什么关系

    CPI反映消费价格变化情况,是一个相对数.GDP反映国民经济生产总量,是一个绝对数.CPI的变动反映经济运行过程中物价变动情况,是观察通货膨胀程度的重要指标,GDP的变化则反映经济的增长情况.经济增长 ...

  7. Linux - 命令行 管道(Pipelines) 具体解释

    命令行 管道(Pipelines) 具体解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/24249529 管道操作符" ...

  8. 【BZOJ2626】JZPFAR kd-tree+堆

    [BZOJ2626]JZPFAR Description 平面上有n个点.现在有m次询问,每次给定一个点(px, py)和一个整数k,输出n个点中离(px, py)的距离第k大的点的标号.如果有两个( ...

  9. Hibernate性能优化

    1.性能是与具体的项目挂钩的,并不是对于A项目某种优化方法好就适用于B项目.性能需要不断的测试检验出来的.....(废话) 2.session.clear()方法的使用,通常session是有缓存的 ...

  10. 九度OJ 1042:Coincidence(公共子序列) (DP)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:2303 解决:1241 题目描述: Find a longest common subsequence of two strings. 输入 ...