C. Remove the Bracket

C. Remove the Bracket

RSJ has a sequence $a$ of $n$ integers $a_1,a_2, \ldots, a_n$ and an integer $s$. For each of $a_2,a_3, \ldots, a_{n-1}$, he chose a pair of non-negative integers $x_i$ and $y_i$ such that $x_i+y_i=a_i$ and $(x_i-s) \cdot (y_i-s) \geq 0$.

Now he is interested in the value $$F = a_1 \cdot x_2+y_2 \cdot x_3+y_3 \cdot x_4 + \ldots + y_{n - 2} \cdot x_{n-1}+y_{n-1} \cdot a_n.$$

Please help him find the minimum possible value $F$ he can get by choosing $x_i$ and $y_i$ optimally. It can be shown that there is always at least one valid way to choose them.

Input

Each test contains multiple test cases. The first line contains an integer $t$ ($1 \le t \le 10^4$) — the number of test cases.

The first line of each test case contains two integers $n$, $s$ ($3 \le n \le 2 \cdot 10^5$; $0 \le s \le 2 \cdot 10^5$).

The second line contains $n$ integers $a_1,a_2,\ldots,a_n$ ($0 \le a_i \le 2 \cdot 10^5$).

It is guaranteed that the sum of $n$ does not exceed $2 \cdot 10^5$.

Output

For each test case, print the minimum possible value of $F$.

Example

input

10
5 0
2 0 1 3 4
5 1
5 3 4 3 5
7 2
7 6 5 4 3 2 1
5 1
1 2 3 4 5
5 2
1 2 3 4 5
4 0
0 1 1 1
5 5
4 3 5 6 4
4 1
0 2 1 0
3 99999
200000 200000 200000
6 8139
7976 129785 12984 78561 173685 15480

output

0
18
32
11
14
0
16
0
40000000000
2700826806

Note

In the first test case, $2\cdot 0+0\cdot 1+0\cdot 3+0\cdot 4 = 0$.

In the second test case, $5\cdot 1+2\cdot 2+2\cdot 2+1\cdot 5 = 18$.

 

解题思路

  这题一看这么多变量不好下手,实际上要想到把其他变量固定而只考虑某个变量的取值。具体来说就是,假设除$x_i$和$y_i$外其他的变量都是固定的值,再来求$F$的最小值。

  这个就好求多了,其中$x_i$和$y_i$能够影响到的项只有$y_{i-1} x_{i} + y_{i} x_{i+1}$,而$y_i = a_i - x_i$,因此就有$y_{i-1} x_{i} + (a_i - x_i) x_{i+1}$。由于只有$x_i$是变量,因此可以发现这个一元线性函数,很明显要使得$y_{i-1} x_{i} + (a_i - x_i) x_{i+1}$取到最小值,那么$x_i$的取值一定是定义域的其中一个端点(此时$y_i$也是其定义域的一个端点)。

  $x_i$的定义域就与$a_i$和$s$有关系了:

  1. 如果$a_i \leq s$,那么$0 \leq x_i \leq a_i$,因此要么是$x_i = 0, \ y_i = a_i$,要么是$x_i = a_i, \ y_i = 0$。
  2. 如果$a_i > s$,同理要么是$x_i = a_i - s, \ y_i = s$,要么是$x_i = s, \ y_i = a_i - s$。

  因此可以发现,当其他变量固定时,要使得$F$取到最小值那么$x_i$和$y_i$应该取定义域的两个端点,有两种组合。剩下的就是枚举$2^n$种情况取最小值就可以了,因此可以考虑用状态机dp。

  定义状态$f(i, 0)$和$f(i, 1)$,其中这里的$0$和$1$表示$x_i$和$y_i$取值的两种组合情况(第$1$种情况就是对第$0$种的$x_i$和$y_i$两两交换一下就可以了)。因此$f(i, 0)$就表示前$i$项和且$x_i,y_i$是第$0$种组合的最小值,同理$f(i, 1)$就表示前$i$项和且$x_i,y_i$是第$1$种组合的最小值。这里的前$i$项和是指$\sum\limits_{j=2}^{i} {y_{j-1}x_{j}}$。状态划分就根据第$i-1$项是哪种组合来转移就可以了,具体看状态转移方程:

\begin{cases}
f(i, 0) = \min\{ {f(i-1,0)} + y_{i-1} \cdot x_{i}, \ {f(i-1,1)} + x_{i-1} \cdot x_{i} \} \\
f(i, 1) = \min\{ {f(i-1,0)} + y_{i-1} \cdot y_{i}, \ {f(i-1,1)} + x_{i-1} \cdot y_{i} \}
\end{cases}

  AC代码如下:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef long long LL;
 5 
 6 const int N = 2e5 + 10;
 7 
 8 LL x[N], y[N];
 9 LL f[N][2];
10 
11 void solve() {
12     int n, m;
13     scanf("%d %d", &n, &m);
14     for (int i = 1; i <= n; i++) {
15         LL v;
16         scanf("%lld", &v);
17         if (i == 1 || i == n) x[i] = y[i] = v;
18         else if (v <= m) x[i] = 0, y[i] = v;
19         else x[i] = v - m, y[i] = m;
20     }
21     for (int i = 2; i <= n; i++) {
22         f[i][0] = min(f[i - 1][0] + y[i - 1] * x[i], f[i - 1][1] + x[i - 1] * x[i]);
23         f[i][1] = min(f[i - 1][0] + y[i - 1] * y[i], f[i - 1][1] + x[i - 1] * y[i]);
24     }
25     printf("%lld\n", f[n][0]);
26 }
27 
28 int main() {
29     int t;
30     scanf("%d", &t);
31     while (t--) {
32         solve();
33     }
34     
35     return 0;
36 }

 

参考资料

  TypeDB Forces 2023 (Div. 1 + Div. 2, Rated, Prizes!) Editorial:https://codeforces.com/blog/entry/112009

  TypeDB Forces 2023 (Div. 1 + Div. 2, Rated, Prizes!)(持续更新):https://www.cnblogs.com/cjjsb/p/17077371.html

posted @ 2023-01-31 16:31  onlyblues  阅读(65)  评论(0编辑  收藏  举报
Web Analytics