【BZOJ 2006】2006: [NOI2010]超级钢琴(RMQ+优先队列)
2006: [NOI2010]超级钢琴
Time Limit: 20 Sec Memory Limit: 552 MB
Submit: 2792 Solved: 1388Description
小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,000k<=500,000-1000<=Ai<=1000,1<=L<=R<=N且保证一定存在满足条件的乐曲Output
只有一个整数,表示乐曲美妙度的最大值。
Sample Input
4 3 2 3
3
2
-6
8Sample 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次之后就是答案。
维护区间最大值我用倍增的。
#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+优先队列)的更多相关文章
- BZOJ 2006: [NOI2010]超级钢琴( RMQ + 堆 )
		
取最大的K个, 用堆和RMQ来加速... ----------------------------------------------------------------- #include<c ...
 - 洛谷P0248 [NOI2010] 超级钢琴 [RMQ,贪心]
		
题目传送门 超级钢琴 题目描述 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的音乐. 这架超级钢琴可以弹奏出n个音符,编号为1至n.第i个音符 ...
 - 【BZOJ 2006】[NOI2010]超级钢琴 ST
		
我们先把所有最左端对应的最优右端入堆,eg: z 在[l,r](由题目给出的L,R决定)之间的最优解 y,然后出堆以后,再入堆z,y-1,z,y+1,那么我们只需要用st找最大前缀和就好了(ST是一 ...
 - 洛谷 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]$是一个定值,所以我们只要在 ...
 - P2048 [NOI2010]超级钢琴 (RMQ,堆)
		
大意: 给定n元素序列a, 定义一个区间的权值为区间内所有元素和, 求前k大的长度在[L,R]范围内的区间的权值和. 固定右端点, 转为查询左端点最小的前缀和, 可以用RMQ O(1)查询. 要求的是 ...
 - BZOJ 2006: [NOI2010]超级钢琴
		
2006: [NOI2010]超级钢琴 Time Limit: 20 Sec Memory Limit: 552 MBSubmit: 2613 Solved: 1297[Submit][Statu ...
 - Bzoj 2006: [NOI2010]超级钢琴  堆,ST表
		
2006: [NOI2010]超级钢琴 Time Limit: 20 Sec Memory Limit: 552 MBSubmit: 2222 Solved: 1082[Submit][Statu ...
 - [BZOJ 2006] [NOI 2010]超级钢琴(贪心+ST表+堆)
		
[BZOJ 2006] [NOI 2010]超级钢琴(贪心+ST表+堆) 题面 给出一个长度为n的序列,选k段长度在L到R之间的区间,一个区间的值等于区间内所有元素之的和,使得k个区间的值之和最大.区 ...
 - bzoj千题计划162:bzoj2006: [NOI2010]超级钢琴
		
http://www.lydsy.com/JudgeOnline/problem.php?id=2006 输出最大的k个 sum[r]-sum[l-1] (L<=r-l+1<=R) 之和 ...
 
随机推荐
- 【洛谷 P1501】 [国家集训队]Tree II(LCT)
			
题目链接 Tree Ⅱ\(=\)[模板]LCT+[模板]线段树2.. 分别维护3个标记,乘的时候要把加法标记也乘上. 还有就是模数的平方刚好爆\(int\),所以开昂赛德\(int\)就可以了. 我把 ...
 - matlab前景分割
			
用最简单的差分法实现了一下前景分割.使用的mall数据集. 思路是这样的:首先设定一个队列的长度,若读取的图片张数少于队列长度则以当前读取到的图片做平均.否则则以队列中的图片做平均. 这样之后和当前图 ...
 - vue-loader 调用了cssLoaders方法配置了css加载器属性。
			
module: { loaders: [ // 这里也是相应的配置,test就是匹配文件,loader是加载器, { test: /\.vue$/, loader: 'vue' }, { test: ...
 - 环境变量配错了   command not found
			
一般就是忘记在PATH 前面加$ 1.可以用whereis或者which命令查看一下有没有这个命令 具体执行which lswhereis ls 2.系统环境变量导致的问题解决方案: exportPA ...
 - apache2启动失败(Failed to start The Apache HTTP Server.)解决方案
			
不知道如何启动apache2就启动不来了. 如下图所示: 即使卸载了重新装也是如此 经过测试卸载并清除软件包的配置即可解决 sudo apt-get purge apache2 sudo apt-g ...
 - Java并发编程(二)
			
1.Lock接口 在Lock接口出现之前,Java程序是靠synchronized关键字实 ...
 - VC RichEdit中英文关键字标红
			
最近需要做vc的RichEdit控件里的内容关键字标红,由于RichEdit的内容可能是中英文混合的,所以需要先转成Unicode,再用wcsstr函数找到关键字出现的位置,再用SetSel.SelS ...
 - git版本控制系统常见操作总结
			
简介 Git是强大的版本控制系统,主要功能是针对代码.配置文件等文本进行版本控制.备份等,同时个人认为还是分发代码的一个不错的方式. 常见用法 #创建远程git仓库 [root@test88 ~]# ...
 - python【项目】:选课系统【简易版】
			
功能要求 角色:学校.学员.课程.讲师要求:1. 创建学校2. 创建课程3. 课程包含,周期,价格,通过学校创建课程4. 通过学校创建班级, 班级关联课程.讲师5. 创建学员时,选择学校,关联班级5. ...
 - Effective STL 阅读笔记: Item 4 ~ 5: Call empty instead of checking size() against zero.
			
Table of Contents 1 Item 4: Call empty instead of checking size() against zero 2 Item 5: Prefer rang ...