2006: [NOI2010]超级钢琴 - BZOJ

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,表示按编号从小到大每个音符的美妙度。
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。

给jzp跪了,想不到竟然可以这样

首先原来有一道这样的题,就是有a,b两个有序数组,c[i,j]表示a[i]+b[i],输出前k小

这个大家都知道,用堆维护每一行的当前最小值(就是最前面的数啦),每次取一个元素,就把这一行的列+1,然后再加进堆

这个我一开始想法也差不多,先处理一个前缀和,区间[l,r]的和就变成了s[r]-s[l-1]所以也变成和上面那个差不多的东西,但是无序

所以我们还要支持查找区间k大,这样复杂度略高

于是jzp就给出了一个更好的,我们用三元组(i,l,r)表示左端点为i,右端点再[l,r]的最大值,一开始显然有n个元素

然后当我们取出元素(i,l,r)时,我们要更新,我们把它拆成两份,假设最大值在k处取得,我们就把(i,l,k-1)和(i,k+1,r)加入堆中

这样复杂度是O((n+k)log(n+k))就毫无压力了

  1 const
  2     maxn=500500;
  3 type
  4     node=record
  5         i,l,r,max:longint;
  6     end;
  7 var
  8     q:array[0..maxn*2]of node;
  9     s:array[0..maxn]of int64;
 10     f:array[0..maxn,0..20]of longint;
 11     n,k,l,r,tot:longint;
 12     ans:int64;
 13
 14 procedure rmq;
 15 var
 16     i,k:longint;
 17 begin
 18     for i:=1 to n do f[i,0]:=i;
 19     k:=0;
 20     while 1<<k<<1<=n do
 21         begin
 22             for i:=1 to n-1<<k<<1+1 do
 23                 if s[f[i,k]]>s[f[i+1<<k,k]] then f[i,k+1]:=f[i,k]
 24                 else f[i,k+1]:=f[i+1<<k,k];
 25             inc(k);
 26         end;
 27 end;
 28
 29 function max(l,r:longint):longint;
 30 var
 31     k:longint;
 32 begin
 33     k:=0;
 34     while r-l+1>1<<k<<1 do inc(k);
 35     if s[f[r-1<<k+1,k]]>s[f[l,k]] then exit(f[r-1<<k+1,k]);
 36     exit(f[l,k]);
 37 end;
 38
 39 procedure swap(var x,y:node);
 40 var
 41     t:node;
 42 begin
 43     t:=x;x:=y;y:=t;
 44 end;
 45
 46 procedure up(x:longint);
 47 var
 48     i:longint;
 49 begin
 50     while x>1 do
 51         begin
 52             i:=x>>1;
 53             if s[q[x].max]-s[q[x].i]> s[q[i].max]-s[q[i].i] then
 54                 begin
 55                     swap(q[i],q[x]);
 56                     x:=i;
 57                 end
 58             else exit;
 59         end;
 60 end;
 61
 62 procedure down(x:longint);
 63 var
 64     i:longint;
 65 begin
 66     i:=x<<1;
 67     while i<=tot do
 68         begin
 69             if (i<tot) and (s[q[i+1].max]-s[q[i+1].i]>s[q[i].max]-s[q[i].i]) then inc(i);
 70             if s[q[i].max]-s[q[i].i]>s[q[x].max]-s[q[x].i] then
 71                 begin
 72                     swap(q[i],q[x]);
 73                     x:=i;i:=x<<1;
 74                 end
 75             else exit;
 76         end;
 77 end;
 78
 79 procedure insert(i,l,r:longint);
 80 begin
 81     if r>n then r:=n;
 82     if l>r then exit;
 83     inc(tot);
 84     q[tot].i:=i;q[tot].l:=l;q[tot].r:=r;
 85     q[tot].max:=max(l,r);
 86     up(tot);
 87 end;
 88
 89 procedure delete;
 90 begin
 91     swap(q[1],q[tot]);
 92     dec(tot);
 93     down(1);
 94 end;
 95
 96 procedure main;
 97 var
 98     i:longint;
 99 begin
100     read(n,k,l,r);
101     for i:=1 to n do read(s[i]);
102     for i:=2 to n do inc(s[i],s[i-1]);
103     rmq;
104     for i:=0 to n-1 do insert(i,i+l,i+r);
105     for i:=1 to k do
106         begin
107             inc(ans,s[q[1].max]-s[q[1].i]);
108             insert(q[1].i,q[1].l,q[1].max-1);insert(q[1].i,q[1].max+1,q[1].r);
109             delete;
110         end;
111     writeln(ans);
112 end;
113
114 begin
115     main;
116 end.

2006: [NOI2010]超级钢琴 - BZOJ

时间: 2024-11-10 09:28:08

2006: [NOI2010]超级钢琴 - BZOJ的相关文章

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

2006: [NOI2010]超级钢琴 Time Limit: 20 Sec  Memory Limit: 552 MBSubmit: 2222  Solved: 1082[Submit][Status][Discuss] Description 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的音乐. 这架超级钢琴可以弹奏出n个音符,编号为1至n.第i个音符的美妙度为Ai,其中Ai可正可负. 一个“超级和弦”由若干个编号连续的音符组成,包含

BZOJ 2006: [NOI2010]超级钢琴

2006: [NOI2010]超级钢琴 Time Limit: 20 Sec  Memory Limit: 552 MBSubmit: 2613  Solved: 1297[Submit][Status][Discuss] Description 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的 音乐. 这架超级钢琴可以弹奏出n个音符,编号为1至n.第i个音符的美妙度为Ai,其中Ai可正可负. 一个“超级 和弦”由若干个编号连续的音符组成,

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

取最大的K个, 用堆和RMQ来加速... ----------------------------------------------------------------- #include<cstdio> #include<algorithm> #include<cstring> #include<queue> using namespace std; typedef long long ll; typedef pair<int, int> p

[BZOJ 2006][NOI2010]超级钢琴(ST表+堆)

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

BZOJ 2006 NOI2010 超级钢琴 划分树+堆

题目大意:给定一个序列,找到k个长度在[l,r]之间的序列,使得和最大 暴力O(n^2logn).肯定过不去 看到这题的第一眼我OTZ了一下午...后来研究了非常久别人的题解才弄明确怎么回事...蒟蒻果然不能理解大神的思路啊0.0 首先维护前缀和,那么以第i个元素结尾的和最大的序列自然就是sum[i]-min{sum[j]}(i-r<=j<=i-l) 然后我们维护一个大根堆.每取走一个以i为结尾的元素,增加sum[i]-2thmin{sum[j]},再取走这个元素就增加sum[i]-3thmi

2006: [NOI2010]超级钢琴|ST表|堆

由于K很小,所以就直接取出最大的K个值加起来即可 考虑一个(i,l,r)表示以i开始以[l,r]中的某个位置结束的区间和的最大值,假设这个位置为p,然后把这些东西都存起来一起扔到堆中,每次取出区间和最大的一个元素,然后继续向堆中添加新的元素,直接对(i,l,p?1),(i,p+1,r)这两个组合再分别找出最大的区间和再扔到堆中,然后重复此过程直到找出前K大 (i,l,r)组合的最大区间和为max(sum[l],sum[l+1]...sum[r])?sum[i?1],找(i,l,r)组合的最大区间

NOI2010超级钢琴 2

2006: [NOI2010]超级钢琴 Time Limit: 20 Sec  Memory Limit: 552 MBSubmit: 1296  Solved: 606[Submit][Status] Description 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的音乐. 这架超级钢琴可以弹奏出n个音符,编号为1至n.第i个音符的美妙度为Ai,其中Ai可正可负. 一个“超级和弦”由若干个编号连续的音符组成,包含的音符个数不少于L且

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

2006: [NOI2010]超级钢琴 Time Limit: 20 Sec  Memory Limit: 552 MBSubmit: 3591  Solved: 1780[Submit][Status][Discuss] Description 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的 音乐. 这架超级钢琴可以弹奏出n个音符,编号为1至n.第i个音符的美妙度为Ai,其中Ai可正可负. 一个"超级 和弦"由若干个编号连续的

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

2006: [NOI2010]超级钢琴 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 3679  Solved: 1828[Submit][Status][Discuss] Description 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的 音乐. 这架超级钢琴可以弹奏出n个音符,编号为1至n.第i个音符的美妙度为Ai,其中Ai可正可负. 一个“超级 和弦”由若干个编号连续的音符组成,