题意:Gildong有一个n个数字的数组a。支持两种操作:1.给一个后缀每个数字增加1
2.给一个后缀每个数字减去1 你可以修改一个数字或者选择不修改,求这个数组每个数字变成一个相等数最少的修改次数。

分析:我们假设最终得到的数字为\(b\)
我们考虑如下的四个数字
\(a_{1}, a_{2}, a_{3}, a_{4}\)
首先是\(a_{1}\)变成b,那么所需要的次数为\(abs(b - a_{1})\),得到
\(b, a_{2} + b - a_{1}, a_{3} + b - a_{1}, a_{4} + b - a_{1}\)
然后我们把\(a_{2} + b - a_{1}\)变成b,所需要的次数为\(abs(b - (a_{2} + b - a_{1})) = abs(a_{1} - a_{2})\),得到
\(b, b, a_{3} + b - a_{1} + b - (a_{2} + b - a_{1}), a_{4} + b - a_{1} + b - (a_{2} + b - a_{1})\)
化简为
\(b, b, b + a_{3} - a_{2}, b + a_{4} - a_{2}\)
然后我们把\(b + a_{3} - a_{2}\)变成b,所需要次数为\(abs(b - (b + a_{3} - a_{2})) = abs(a_{2} - a_{3})\)得到
\(b, b, b, b + a_{4} - a_{2} + b - (b + a_{3} - a_{2})\) = \(b, b, b, b + a_{4} - a_{3}\)
然后我们最后只需要\(abs(a_{3} - a_{4})\),即可把整个数组变成b。

总共的次数为\(b + abs(b - a_{1}) + abs(a_{1} - a_{2}) + abs(a_{2} - a_{3}) + abs(a_{3} - a_{4})\)
当b为\(a_{1}\)时,前面的项可以消掉,变成0,即\(abs(a_{1} - a_{2}) + abs(a_{2} - a_{3}) + abs(a_{3} - a_{4})\)
观察这个式子,我们修改一个数可以像\(a_{2}\)一样,影响两个式子,也可以像\(a_{1}\)\(a_{4}\)一样,影响一个式子,
所以,当我们修改一个数的时候,对于像\(abs(a_{1} - a_{2}) + abs(a_{2} - a_{3})\)这样的式子,我们化简,为
\(y = abs(c1 - x) + abs(x - c2)\)\(x\)是我们需要修改的数,我们应该让这个式子尽量小,这是一个绝对值函数,
函数图像如下:这是\(f(x)=abs(3-x)+abs(x-5)\)的图像,当x为[3, 5]之间的时候,取到最小值,我们只需要分类讨论下即可,

因此,我们只需要对每一项做差,查看差值的大小,然后就可以求得答案。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <map>
#include <set>
#include <vector>
#include <algorithm>

using namespace std;
const int N = 200005;
typedef long long ll;
ll a[N];
int main()
{
	int t;
	scanf("%d", &t);
	while(t--)
	{
		int n;
		scanf("%d", &n);

		for(int i = 1; i <= n; ++i) scanf("%lld", &a[i]);

		//vector<int> v;
		ll mx = 0;
		ll sum = 0;
		for(int i = 2; i < n; ++i)
		{
			ll tmp = 0;
			if(a[i - 1] > 0 && a[i + 1] > 0)
			{
				tmp = abs(a[i - 1] - a[i + 1]);
			}
			else if(a[i - 1] < 0 && a[i + 1] > 0)
			{
				tmp = abs(a[i - 1]) + abs(a[i + 1]);
			}
			else if(a[i - 1] > 0 && a[i + 1] < 0)
			{
				tmp = abs(a[i - 1]) + abs(a[i + 1]);
			}
			else if(a[i - 1] < 0 && a[i + 1] < 0)
			{
				tmp = abs(a[i - 1] - a[i + 1]);
			}
			else 
			{
				tmp = abs(a[i - 1]) + abs(a[i + 1]);
			}
			ll now = abs(a[i - 1] - a[i]) + abs(a[i] - a[i + 1]);
			//cout << tmp - now << "***" << endl;
			mx = min(mx, tmp - now);
			//v.push_back(abs(abs(a[i + 1] + a[i - 1]) - a[i]));	
		}
		mx = min(mx, -abs(a[1] - a[2]));
		mx = min(mx, -abs(a[n - 1] - a[n]));
		//cout << mx << "---" << endl;
		for(int i = 1; i < n; ++i)
		{
			//cout << a[i] << "-" << a[i + 1] << endl;
			sum += abs(a[i] - a[i + 1]);
		}

		printf("%lld\n", sum + mx);
	}



	return 0;
}