E. Kolya and Movie Theatre

E. Kolya and Movie Theatre

Recently, Kolya found out that a new movie theatre is going to be opened in his city soon, which will show a new movie every day for n days. So, on the day with the number 1in, the movie theatre will show the premiere of the i-th movie. Also, Kolya found out the schedule of the movies and assigned the entertainment value to each movie, denoted by ai.

However, the longer Kolya stays without visiting a movie theatre, the larger the decrease in entertainment value of the next movie. That decrease is equivalent to dcnt, where d is a predetermined value and cnt is the number of days since the last visit to the movie theatre. It is also known that Kolya managed to visit another movie theatre a day before the new one opened — the day with the number 0. So if we visit the movie theatre the first time on the day with the number i, then cnt — the number of days since the last visit to the movie theatre will be equal to i.

For example, if d=2 and a=[3,2,5,4,6], then by visiting movies with indices 1 and 3, cnt value for the day 1 will be equal to 10=1 and cnt value for the day 3 will be 31=2, so the total entertainment value of the movies will be a1d1+a3d2=321+522=2.

Unfortunately, Kolya only has time to visit at most m movies. Help him create a plan to visit the cinema in such a way that the total entertainment value of all the movies he visits is maximized.

Input

Each test consists of multiple test cases. The first line contains a single integer t (1t104) — the number of test cases. The description of the test cases follows.

The first line of each test case contains three integers n, m, and d (1n2105, 1mn, 1d109).

The second line of each set of input data contains n integers a1,a2,,an (109ai109) — the entertainment values of the movies.

It is guaranteed that the sum of n over all test cases does not exceed 2105.

Output

For each test case, output a single integer — the maximum total entertainment value that Kolya can get.

Example

input

复制代码
6
5 2 2
3 2 5 4 6
4 3 2
1 1 1 1
6 6 6
-82 45 1 -77 39 11
5 2 2
3 2 5 4 8
2 1 1
-1 2
6 3 2
-8 8 -2 -1 9 0
复制代码

output

2
0
60
3
0
7

Note

The first test case is explained in the problem statement.

In the second test case, it is optimal not to visit any movies.

In the third test case, it is optimal to visit movies with numbers 2, 3, 5, 6, so the total entertainment value of the visited movies will be 4562+161+3962+1161=60.

 

解题思路

  没发现式子的性质没做出来,好似喵。

  假设从小到大选择了k个下标i1,i2,,ik,此时的结果是(ai1di1)+(ai2d(i2i1))++(aikd(ikik1))= (ai1+ai2++aik)d(i1+i2i1+i3i2++ikik1)= (ai1+ai2++aik)dik

  可以发现结果中减去的部分只取决于最大的下标,因此可以从小到大枚举最后一个下标k选什么,然后再从前面的下标i[1,k1]中选出最大的m1ai(此时已经选择了ak),来使得结果最大。因此可以开个堆来维护前缀的前m1个最大值以及他们的和。需要注意的是,如果ak0那么我们永远不会选择这个元素,从上面的式子可以看出,如果k不作为最大的下标,那么我们将ak删除结果不会变小,而如果k作为最大的下标,那么删除akdik变小,结果会变小。总之删除ak结果一定不会变小。

  AC代码如下,时间复杂度为O(nlogm)

复制代码
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef long long LL;
 5 
 6 const int N = 2e5 + 10;
 7 
 8 int a[N];
 9 
10 void solve() {
11     int n, m, d;
12     scanf("%d %d %d", &n, &m, &d);
13     for (int i = 1; i <= n; i++) {
14         scanf("%d", a + i);
15     }
16     priority_queue<int, vector<int>, greater<int>> pq;
17     LL ret = 0, s = 0;
18     for (int i = 1; i <= n; i++) {
19         if (a[i] <= 0) continue;
20         s += a[i];
21         if (pq.size() == m) {
22             s -= pq.top();
23             pq.pop();
24         }
25         pq.push(a[i]);
26         ret = max(ret, s - 1ll * i * d);
27     }
28     printf("%lld\n", ret);
29 }
30 
31 int main() {
32     int t;
33     scanf("%d", &t);
34     while (t--) {
35         solve();
36     }
37     
38     return 0;
39 }
复制代码

 

参考资料

  Codeforces Round #894 (Div.3) Editorial:https://codeforces.com/blog/entry/119715

posted @   onlyblues  阅读(48)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
Web Analytics
点击右上角即可分享
微信分享提示