这题自然而然想到差分,数组a[i]表示各个员工到手的工资,d[i] = a[i] - a[i - 1]表示编号为i减去编号为i-1员工工资的差,让所有人工资相等即是让所有d[i]为0,小马哥的每次操作是将编号在区间【l,r】的员工工资加1或减1,即对应在差分数组中,(加工资,d[l] ++, d[r+1] -- ;降工资, d[i] -- , d[r + 1] ++ ), 实际上一次操作只能达到对两个差分数组中的值一个进行加一,一个进行减一的效果(当l或r是边界时,对应的差分数组值不需要修改),那么我们只需要统计原来的差分数组中,正数的绝对值之和(需要减1的次数),负数的绝对值之和(需要加1的次数),二者取较大的即为需要操作的次数。
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int N = 100010;
int a[N], d[N];
typedef long long LL;
int main()
{
int n;
cin >> n;
for (int i = 0; i < n; i ++ )
{
scanf("%d", &a[i]);
if (i >= 1) d[i] = a[i] - a[i - 1];
}
LL res_p = 0, res_n = 0; // 正数绝对值之和,负数绝对值之和
for (int i = 1; i < n; i ++ )
{
if (d[i] > 0) res_p += d[i];
else res_n += -d[i];
}
cout << max(res_n, res_p) << endl;
return 0;
}