2006: [NOI2010]超级钢琴

Time Limit: 20 Sec  Memory Limit: 552 MB
Submit: 2613  Solved: 1297
[Submit][Status][Discuss]

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

 

[Submit][Status][Discuss]

学习的题解,转载在下——

堆+RMQ

定义一个四元组(i,l,r,t)表示是以第i个为开头的,结尾在l-r之间(满足长度>=L,<=R),且结尾在t的权值和最大。

首先把以每一位开头的四元组加入堆,此时的l,r是恰好满足长度>=L,<=R;

堆中排序的关键字是权值之和。

然后把堆顶取出(i,l,r,t),然后再把(i,l,t-1,t')和(i,t+1,r,t'')加入堆中(因为要满足任意两个序列不同的条件)

那么四元组中的t如何快速求出?

用RMQ即可:维护前缀和,权值和就是sum[t]-sum[i-1],对于用一个四元组sum[i-1]相同,因此只要找到l-r中sum[i]最大的即可。

  1. #include <queue>
  2. #include <cstdio>
  3.  
  4. inline int nextChar(void)
  5. {
  6. const static int siz = ;
  7.  
  8. static char buf[siz];
  9. static char *hd = buf + siz;
  10. static char *tl = buf + siz;
  11.  
  12. if (hd == tl)
  13. fread(hd = buf, , siz, stdin);
  14.  
  15. return *hd++;
  16. }
  17.  
  18. inline int nextInt(void)
  19. {
  20. register int ret = ;
  21. register int neg = false;
  22. register int bit = nextChar();
  23.  
  24. for (; bit < ; bit = nextChar())
  25. if (bit == '-')neg ^= true;
  26.  
  27. for (; bit > ; bit = nextChar())
  28. ret = ret * + bit - ;
  29.  
  30. return neg ? -ret : ret;
  31. }
  32.  
  33. const int siz = ;
  34.  
  35. int N, M, L, R;
  36.  
  37. int num[siz];
  38. int sum[siz];
  39.  
  40. int st[siz][], log[siz];
  41.  
  42. inline void preworkRMQ(void)
  43. {
  44. for (int i = ; i <= N; ++i)
  45. st[i][] = i;
  46.  
  47. for (int i = ; ( << i) <= N; ++i)
  48. for (int j = ; j + ( << i) - <= N; ++j)
  49. {
  50. int x = st[j][i - ];
  51. int y = st[j + ( << (i - ))][i - ];
  52. st[j][i] = sum[x] > sum[y] ? x : y;
  53. }
  54.  
  55. log[] = -;
  56.  
  57. for (int i = ; i <= N; ++i)
  58. log[i] = log[i >> ] + ;
  59. }
  60.  
  61. inline int query(int l, int r)
  62. {
  63. if (l == r)
  64. return l;
  65.  
  66. int t = log[r - l + ];
  67.  
  68. int x = st[l][t];
  69. int y = st[r - ( << t) + ][t];
  70.  
  71. return sum[x] > sum[y] ? x : y;
  72. }
  73.  
  74. struct data
  75. {
  76. int p, t, l, r;
  77.  
  78. data(void) {};
  79. data(int a, int b, int c, int d) :
  80. p(a), t(b), l(c), r(d) {};
  81. };
  82.  
  83. inline bool operator < (const data &a, const data &b)
  84. {
  85. return sum[a.t] - sum[a.p - ] < sum[b.t] - sum[b.p - ];
  86. }
  87.  
  88. std::priority_queue<data> h;
  89.  
  90. signed main(void)
  91. {
  92. N = nextInt();
  93. M = nextInt();
  94. L = nextInt();
  95. R = nextInt();
  96.  
  97. for (int i = ; i <= N; ++i)
  98. num[i] = nextInt();
  99.  
  100. for (int i = ; i <= N; ++i)
  101. sum[i] = sum[i - ] + num[i];
  102.  
  103. preworkRMQ();
  104.  
  105. long long ans = ;
  106.  
  107. for (int i = ; i <= N - L + ; ++i)
  108. {
  109. int l = i + L - ;
  110. int r = i + R - ;
  111.  
  112. if (r > N)
  113. r = N;
  114.  
  115. h.push(data(i, query(l, r), l, r));
  116. }
  117.  
  118. for (int i = ; i <= M; ++i)
  119. {
  120. data top = h.top(); h.pop();
  121.  
  122. ans += sum[top.t] - sum[top.p - ];
  123.  
  124. if (top.t > top.l)
  125. h.push(data(top.p, query(top.l, top.t - ), top.l, top.t - ));
  126. if (top.t < top.r)
  127. h.push(data(top.p, query(top.t + , top.r), top.t + , top.r));
  128. }
  129.  
  130. printf("%lld\n", ans);
  131. }

@Author: YouSiki

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

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

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

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

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

  3. 洛谷 P2048 BZOJ 2006 [NOI2010]超级钢琴

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

  4. BZOJ.2006.[NOI2010]超级钢琴(贪心 堆)

    BZOJ 洛谷 思路和BZOJ3784一样,用前缀和+堆维护.做那题吧,不赘述啦. (没错我就是水一个AC) //54620kb 1060ms #include <queue> #incl ...

  5. bzoj 2006 [NOI2010]超级钢琴——ST表+堆

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2006 每个右端点的左端点在一个区间内:用堆记录端点位置.可选区间,按价值排序:拿出一个后也许 ...

  6. BZOJ 2006 [NOI2010]超级钢琴 (堆+主席树)

    题面:BZOJ传送门 洛谷传送门 让你求前$K$大的子序列和,$n\leq 5*10^{5}$ 只想到了个$nlog^{2}n$的做法,似乎要被卡常就看题解了.. 好神奇的操作啊,我傻了 我们把序列和 ...

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

    题目大意:给定一个序列.找到k个长度在[l,r]之间的序列.使得和最大 暴力O(n^2logn),肯定过不去 看到这题的第一眼我OTZ了一下午... 后来研究了非常久别人的题解才弄明确怎么回事...蒟 ...

  8. BZOJ 2006: [NOI2010]超级钢琴 [ST表+堆 | 主席树]

    题意: 一个序列,求k个不相同的长度属于\([L,R]\)的区间使得和最大 前缀和,对于每个r找最小的a[l] 然后我yy了一个可持久化线段树做法...也许会T 实际上主席树就可以了,区间k小值 然后 ...

  9. bzoj 2006: [NOI2010]超级钢琴【st表+堆】

    设计一个五元组(i,l,r,p,v),表示在以i为左端点,右端点落在(l,r)中的情况下,取最大值v时右端点落在p.把这个五元组塞到优先队列里,以v排序,每次取出一个,然后把这个取过的五元组分成两个( ...

随机推荐

  1. gearman 安装

    yum install gperfyum install libevent-develyum install libuuid-develwget https://launchpad.net/gearm ...

  2. Canvas的width,height 和 样式中Canvas的width,height

    控制Canvas的大小,有两种方式: 1:直接设置Canvas标签上的书width,height属性值; 2:通过Css设置Canvas的width,height; 这两种方式,区别是很大的. 1:C ...

  3. ipython notebook 浏览器中编写数学公式和现实

    Python Notebook简介1 http://www.cnblogs.com/cbscan/p/3545084.html $ python -m IPython http://pypi.pyth ...

  4. React Native学习笔记之2

    1:如何创建一个react native工程 首先进入到指定文件夹里面,然后在终端执行react-native init ReactNativeProject :其中ReactNativeProjec ...

  5. ERR_CONTENT_DECODING_FAILED错误的原因和解决办法

    1. ERR_CONTENT_DECODING_FAILED错误的原因 这种错误通常发生于Http请求中的头部信息标识内容是gzip编码的,但实际上不是. 2. ERR_CONTENT_DECODIN ...

  6. CANopen学习——感性认知

    看不懂的知识硬着头皮也要看.读了当时虽然不理解,但脑子里对其相关名词.概念有印象,继续看下去,多读几遍,一定会在某个地方顿悟.  CAN总线只是定义了物理层和数据链路层,并没有定义应用层.这么优秀的总 ...

  7. Laravel中的ajax跨域请求

    最近接触Laravel框架ajax跨域请求的过程中遇到一些问题,在这里做下总结. 一开始发起ajax请求一直报500错误,搜索相关资料后发现Laravel要允许跨域请求可以加入Cors中间件,代码如下 ...

  8. Cookie和Session的那些事儿

    Cookie和Session都是为了保持用户的访问状态,一方面为了方便业务实现,另一方面为了简化服务端的程序设计,提高访问性能.Cookie是客户端(也就是浏览器端)的技术,设置了Cookie之后,每 ...

  9. [Network Analysis] 复杂网络分析总结

    在我们的现实生活中,许多复杂系统都可以建模成一种复杂网络进行分析,比如常见的电力网络.航空网络.交通网络.计算机网络以及社交网络等等.复杂网络不仅是一种数据的表现形式,它同样也是一种科学研究的手段.复 ...

  10. [LeetCode] Evaluate Reverse Polish Notation 计算逆波兰表达式

    Evaluate the value of an arithmetic expression in Reverse Polish Notation. Valid operators are +, -, ...