题意:给定序列 ${a_n}$,每次可操作:选定区间 $[l, r]$,使得 $a_l$ 到 $a_r$ 中的所有数均加 1 或者均减 1 ,求最少要多少次操作才能使得所有元素的值相同,并且求最少次操作后序列的种类有多少种
这里的思路是用到差分
根据差分序列的定义,有
$$
b_1 = a_1\\\\b_2 = a_2 - a_1\\\\…\\\\b_n = a_n - a_{n - 1}
$$
问题就转化成,最少要进行多少次操作,使得 ${b_2,…,b_n}$ 序列变成全 0,$b_1$ 自由,得到的种类数就是 $b_1$ 可以取多少个。
问题等价转换之后,有一个很大的好处就是,操作对 ${b_n}$ 序列就是每次选取区间 $[l, r]$ 使得 $b_l + 1$ , $b_{r + 1} - 1$ 或者是 $b_l - 1, b_{r + 1} + 1$ 只有两个值进行改变。
对 ${b_n}$ 序列进行操作,可以分成下面四类
① $2 <= L <= R <= n - 1:$ 在 $b_2-b_n$ 种某一个数加一某一个数减一
② $L = 1, R <= n - 1:$
③ $2 <= L, R = n:$
④ $L = 1, R = n:$ 此操作无意义。
这样首先进行①操作,直到 ① 区间中不同时存在大于零和小于零的值;
然后执行 ② 或 ③ 操作把 ① 区间内的值给消去;
假设原始 ${b_n}$ 序列中,有 $p$ 个正数,有 $q$ 个负数,那么就需要先进行 $min(p, q)$ 个操作,然后再执行 $|p - q|$ 个 ② 或 ③ 操作使得 $b_2,…,b_n$ 变成0.
那么整个过程就以共要执行 $min(p, q) + |p - q| = max(p, q)$ 次操作,最终的种类有 $|p - q| + q$ 种。
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e5 + 17;
int a[N], b[N];
signed main(){
int n;
cin >> n;
for(int i = 1; i <= n; ++i) cin >> a[i];
b[1] = a[1];
for(int i = 2; i <= n; ++i) b[i] = a[i] - a[i - 1];
int p = 0, q = 0;
for(int i = 2; i <= n; ++i)
if(b[i] > 0) p += b[i];
else q -= b[i];
cout << max(p, q) << endl << abs(p - q) + 1;
return 0;
}