2006: [NOI2010]超级钢琴

Time Limit: 20 Sec  Memory Limit: 552 MB
Submit: 2792  Solved: 1388

Description

小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的
音乐。 这架超级钢琴可以弹奏出n个音符,编号为1至n。第i个音符的美妙度为Ai,其中Ai可正可负。 一个“超级
和弦”由若干个编号连续的音符组成,包含的音符个数不少于L且不多于R。我们定义超级和弦的美妙度为其包含的
所有音符的美妙度之和。两个超级和弦被认为是相同的,当且仅当这两个超级和弦所包含的音符集合是相同的。 
小Z决定创作一首由k个超级和弦组成的乐曲,为了使得乐曲更加动听,小Z要求该乐曲由k个不同的超级和弦组成。
我们定义一首乐曲的美妙度为其所包含的所有超级和弦的美妙度之和。小Z想知道他能够创作出来的乐曲美妙度最
大值是多少。

Input

第一行包含四个正整数n, k, L, R。其中n为音符的个数,k为乐曲所包含的超级和弦个数,L和R分别是超级和弦所
包含音符个数的下限和上限。 接下来n行,每行包含一个整数Ai,表示按编号从小到大每个音符的美妙度。
N<=500,000
k<=500,000
-1000<=Ai<=1000,1<=L<=R<=N且保证一定存在满足条件的乐曲

Output

只有一个整数,表示乐曲美妙度的最大值。

Sample Input

4 3 2 3
3
2
-6
8

Sample Output

11

【样例说明】
共有5种不同的超级和弦:
音符1 ~ 2,美妙度为3 + 2 = 5
音符2 ~ 3,美妙度为2 + (-6) = -4
音符3 ~ 4,美妙度为(-6) + 8 = 2
音符1 ~ 3,美妙度为3 + 2 + (-6) = -1
音符2 ~ 4,美妙度为2 + (-6) + 8 = 4
最优方案为:乐曲由和弦1,和弦3,和弦5组成,美妙度为5 + 2 + 4 = 11。

HINT

Source

【分析】

  好蠢啊没想到。。

  怎么说以为以i为结尾的每一个都要考虑啊才可以。

  其实整体考虑,每次取i开始的最优值就好了。

  具体:

我们处理出这样一个东西(i,L,R)表示当这个和弦的左端点为i时在上限和下限中的最优值。(也就是右端点在[i+l-1,i+r-1]中) 
我们将第一步处理出来的所有最优值扔到一个堆里面,然后每次从堆中选取最大的出来,将ans加上这个数。假设我们在这段区间中选取最优值得位置为where,那么我们就这段区间[L,R]裂解成两段区间[L,where-1]和[where+1,R],再讲这两段区间放到堆里面。 
这样其实就是每次选取了一个最优值,然后把那些小于最优值的数放进去。 
选取了K次之后就是答案。

来自:http://blog.csdn.net/fzhvampire/article/details/46830633

  维护区间最大值我用倍增的。

 #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
#define Maxn 500010
#define LL long long int a[Maxn],sm[Maxn];
int n,k,L,R; int mymin(int x,int y) {return x<y?x:y;}
int mymax(int x,int y) {return x>y?x:y;} struct node
{
int x,y,l,r,w;
friend bool operator < (node x,node y)
{
return x.w<y.w;
}
}; int mx[Maxn][],id[Maxn][]; void rmq_init()
{
for(int i=;i<=n;i++) mx[i][]=sm[i],id[i][]=i;
for(int j=;(<<j)<=n+;j++)
for(int i=;i+(<<j)-<=n;i++)
{
if(mx[i][j-]>mx[i+(<<j-)][j-]) mx[i][j]=mx[i][j-],id[i][j]=id[i][j-];
else mx[i][j]=mx[i+(<<j-)][j-],id[i][j]=id[i+(<<j-)][j-];
// mx[i][j]=mymax(mx[i][j-1],mx[i+(1<<j-1)][j-1]);
}
} int nid;
int rmq(int x,int y)
{
int j=;
while(x+(<<j)-<=y) j++;j--;
if(mx[x][j]>mx[y-(<<j)+][j]) {nid=id[x][j];return mx[x][j];}
else {nid=id[y-(<<j)+][j];return mx[y-(<<j)+][j];}
// return mymax(mx[x][j],mx[y-(1<<j)+1][j]);
} priority_queue<node > q; int main()
{
scanf("%d%d%d%d",&n,&k,&L,&R);
sm[]=;
for(int i=;i<=n;i++)
{
int x;
scanf("%d",&x);
sm[i]=sm[i-]+x;
}
rmq_init();
while(!q.empty()) q.pop();
for(int i=;i<=n-L;i++)
{
int ll,rr;
ll=i+L;rr=mymin(i+R,n);
int maxx=rmq(ll,rr);
node tt;
tt.x=i;tt.y=nid;tt.l=ll;tt.r=rr;tt.w=maxx-sm[i];
q.push(tt);
}
LL ans=;
for(int i=;i<=k;i++)
{
node tt=q.top(),t1;q.pop();
ans+=tt.w;
if(tt.l<tt.y)
{
t1=tt;int maxx=rmq(tt.l,tt.y-);
t1.y=nid;t1.w=maxx-sm[tt.x];
t1.r=tt.y-;
q.push(t1);
}
if(tt.y<tt.r)
{
t1=tt;int maxx=rmq(tt.y+,tt.r);
t1.y=nid;t1.w=maxx-sm[tt.x];
t1.l=tt.y+;
q.push(t1);
}
}
printf("%lld\n",ans);
return ;
}

  2017-03-24 20:11:14

【BZOJ 2006】2006: [NOI2010]超级钢琴(RMQ+优先队列)的更多相关文章

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

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

  2. 洛谷P0248 [NOI2010] 超级钢琴 [RMQ,贪心]

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

  3. 【BZOJ 2006】[NOI2010]超级钢琴 ST

    我们先把所有最左端对应的最优右端入堆,eg: z  在[l,r](由题目给出的L,R决定)之间的最优解 y,然后出堆以后,再入堆z,y-1,z,y+1,那么我们只需要用st找最大前缀和就好了(ST是一 ...

  4. 洛谷 P2048 [NOI2010]超级钢琴(优先队列,RMQ)

    传送门 我们定义$(p,l,r)=max\{sum[t]-sum[p-1],p+l-1\leq t\leq p+r-1 \}$ 那么因为对每一个$p$来说$sum[p-1]$是一个定值,所以我们只要在 ...

  5. P2048 [NOI2010]超级钢琴 (RMQ,堆)

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

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

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

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

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

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

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

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

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

随机推荐

  1. ubuntu11下安装文件

    1.ubuntu11下安装.run文件 首先右键单击这个文件,在properties-permissions那里选择允许以程序执行(打钩Allow executing file as program) ...

  2. 【POJ】3177 Redundant Paths

    [算法]边双连通分量 [题意&题解]http://blog.csdn.net/geniusluzh/article/details/6619575 (注意第一份代码是错误的) 一些细节: 1. ...

  3. 【CodeForces】915 D. Almost Acyclic Graph 拓扑排序找环

    [题目]D. Almost Acyclic Graph [题意]给定n个点的有向图(无重边),问能否删除一条边使得全图无环.n<=500,m<=10^5. [算法]拓扑排序 [题解]找到一 ...

  4. F - Warm up HDU - 4612 tarjan缩点 + 树的直径 + 对tajan的再次理解

    题目链接:https://vjudge.net/contest/67418#problem/F 题目大意:给你一个图,让你加一条边,使得原图中的桥尽可能的小.(谢谢梁学长的帮忙) 我对重边,tarja ...

  5. py,pyc,pyw文件的区别和使用

    熟悉python编程的都知道,python三种最常见的py文件格式,.py,.pyc,.pyw,下面说一说它们各自的使用. py文件 python最常见的文件,是python项目的源码: 文件执行时l ...

  6. git@oschina.net源代码管理使用日记【转】

    转自:https://www.cnblogs.com/Juvy/p/3556902.html git的优势: 1 可以创建分支: 2 版本控制是基于每一次提交的,而不需要考虑每次提交了多少个文件. 下 ...

  7. 用C#实现通过串口对设备的数据采集--Server层

    今天中午没睡午觉,头昏眼花的,实在写不了代码,把这几天写的Server层数据采集的程序整理了一下. WatrLevelDataCollectServer.cs using System; using ...

  8. shell source命令说明

    当我修改了/etc/profile文件,我想让它立刻生效,而不用重新登录:这时就想到用source命令,如:source /etc/profile对source进行了学习,并且用它与sh 执行脚本进行 ...

  9. 【Learn】CSS定义

    CSS基础语法 本文用于介绍CSS相关的知识,用于记录自己的学习笔记.由于我已经熟悉了部分的HTML,所以相关的概念也不在这里进行描述了,直接写自己的一些心得感悟. 1.CSS规则 CSS是由两个主要 ...

  10. aws rds

    1.还原快照,注意设置安全组的问题:不然会导致还原后连接不上: