D. Running Miles

D. Running Miles

There is a street with $n$ sights, with sight number $i$ being $i$ miles from the beginning of the street. Sight number $i$ has beauty $b_i$. You want to start your morning jog $l$ miles and end it $r$ miles from the beginning of the street. By the time you run, you will see sights you run by (including sights at $l$ and $r$ miles from the start). You are interested in the $3$ most beautiful sights along your jog, but every mile you run, you get more and more tired.

So choose $l$ and $r$, such that there are at least $3$ sights you run by, and the sum of beauties of the $3$ most beautiful sights minus the distance in miles you have to run is maximized. More formally, choose $l$ and $r$, such that $b_{i_1} + b_{i_2} + b_{i_3} - (r - l)$ is maximum possible, where $i_1, i_2, i_3$ are the indices of the three maximum elements in range $[l, r]$.

Input

The first line contains a single integer $t$ ($1 \leq t \leq 10^5$) — the number of test cases.

The first line of each test case contains a single integer $n$ ($3 \leq n \leq 10^5$).

The second line of each test case contains $n$ integers $b_i$ ($1 \leq b_i \leq 10^8$) — beauties of sights $i$ miles from the beginning of the street.

It's guaranteed that the sum of all $n$ does not exceed $10^5$.

Output

For each test case output a single integer equal to the maximum value $b_{i_1} + b_{i_2} + b_{i_3} - (r - l)$ for some running range $[l, r]$.

Example

input

8
1
22
299999996

output

8
1
22
299999996

Note

In the first example, we can choose $l$ and $r$ to be $1$ and $5$. So we visit all the sights and the three sights with the maximum beauty are the sights with indices $1$, $3$, and $5$ with beauties $5$, $4$, and $3$, respectively. So the total value is $5 + 4 + 3 - (5 - 1) = 8$.

In the second example, the range $[l, r]$ can be $[1, 3]$ or $[2, 4]$, the total value is $1 + 1 + 1 - (3 - 1) = 1$.

 

解题思路

  比赛的时候写了个假双指针的做法,然后动态规划又没想到怎么做。其实只要想到把公式变一下就能做出来了。

  首先根据贪心思想,对于区间$[l,r]$,若要让$b_{i_1} + b_{i_2} + b_{i_3} - (r - l)$取到最大值,那么其中两个最大元素必然在区间的两个端点,即$a_l, a_r \in \{ {b_{i_1}, b_{i_2}, b_{i_3}} \}$。否则我们可以通过右移左端点$l$或者左移右端点$r$,使得$[l,r]$中的$b_{i_1}, b_{i_2}, b_{i_3}$不变,而$r-l$变小,那么$b_{i_1} + b_{i_2} + b_{i_3} - (r - l)$就会变大。

  因此,不失一般性,我们假设$i_1 = l$,$i_3 = r$,$i_2 = i \in (l,r)$,那么公式就会变成$b_l + b_i + b_r - (r-l) = a_i + (a_l + l) + (a_r - r)$。可以发现$a_l + l$的取值仅取决于$l$,$a_r - r$的取值仅取决于$r$,因此可以枚举中间元素$a_i$,然后在$l \in [1, i-1]$中求$a_l + l$的最大值,在$r \in [i+1, n]$中求$a_r - r$的最大值。前后缀的最大值可以预处理出来。

  AC代码如下,时间复杂度为$O(n)$:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int N = 1e5 + 10, INF = 0x3f3f3f3f;
 5 
 6 int a[N];
 7 int l[N], r[N];
 8 
 9 void solve() {
10     int n;
11     scanf("%d", &n);
12     l[0] = r[n + 1] = -INF;
13     for (int i = 1; i <= n; i++) {
14         scanf("%d", a + i);
15         l[i] = max(l[i - 1], a[i] + i);
16     }
17     for (int i = n; i; i--) {
18         r[i] = max(r[i + 1], a[i] - i);
19     }
20     int ret = 0;
21     for (int i = 1; i <= n; i++) {
22         ret = max(ret, a[i] + l[i - 1] + r[i + 1]);
23     }
24     printf("%d\n", ret);
25 }
26 
27 int main() {
28     int t;
29     scanf("%d", &t);
30     while (t--) {
31         solve();
32     }
33     
34     return 0;
35 }

 

参考资料

  Codeforces Round #870 (Div. 2) Editorial:https://codeforces.com/blog/entry/115892

posted @ 2023-05-06 09:05  onlyblues  阅读(162)  评论(0编辑  收藏  举报
Web Analytics