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. .Net各版本新特性

    序言 C# 1.0 (2002) public interface IDateProvider { DateTime GetDate(); } 隐式接口实现 public class DefaultD ...

  2. 网络流入门--最大流算法Dicnic 算法

    感谢WHD的大力支持 最早知道网络流的内容便是最大流问题,最大流问题很好理解: 解释一定要通俗! 如右图所示,有一个管道系统,节点{1,2,3,4},有向管道{A,B,C,D,E},即有向图一张.  ...

  3. cin循环输入控制问题

    之前写一个简单的输入节点值自动生成链表的测试程序,发现cin的输入控制好像在VC++6.0和VS2010中不一样,特此记录. 现在有以下代码: vector<int> ivec; int ...

  4. MySQL指定使用某个索引查询语句

    查询语句查询emp_no,所以先查询emp_no的索引使用primary select emp_no,salary from salaries use index(s_f_t) where emp_n ...

  5. Apache+jboss群集部署

    Jboss default方式上的Cluster配置[二] - 操作系统http://www.myexception.cn/operating-system/862858.html Jboss def ...

  6. 关于"轉淚點"与"轉捩點"

    经常看台湾偶像剧或台湾综艺节目的人,一定听过"转泪点"这个词,虽然我一直不知道这三个字具体是怎么写, 但其意思很容易明白,就是"转折点"的意思.今天无聊在看凤凰 ...

  7. 无状态Http

    无状态的根本原因 浏览器和服务器使用socket通信,服务器将请求结果返回给浏览器后,会关闭当前socket连接.而且服务器会在处理页面完毕后销毁页面对象. 应用层面的原因 浏览器和服务器之间通信都遵 ...

  8. rpmdb: Thread/process 9180/139855524558592 failed: Thread died in Berkeley DB library

    使用yum安装出现问题:rpmdb: Thread/process 9180/139855524558592 failed: Thread died in Berkeley DB library 解决 ...

  9. final修饰的变量是引用不能改变还是引用的对象不能改变

    我们都知道final修饰变量时 会变为常量,但是使 用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变? 下面让我们来看这段代码: /** * 验证final修饰的变量是引用不能变, ...

  10. [ python ] 接口类和抽象类

    接口类 继承有两种用途:1. 继承基类的方法,并且做出自己的改变或者扩展(代码重用)2. 申明某个子类兼容于某基类,定义一个接口类interface,接口类定义了一些接口名且未实现接口的功能,子类继承 ...