思路
参考题解:我们要将所有数字变成一样其实也就是让差分数组中的正负值都变成零, 联想到模拟, 我们肯定要先让a[1] == a[2], 再依次让前1 ~ i的数字一样, 假设我们改变到了x, 如果d[x] = a[x] - a[x - 1] > 0, 说明a[i]这个数偏大, 我们需要将前1 ~ x - 1中的数都变成和a[x]一样大而如果((x - 1) % k != 0)则无法实现,如果d[x] < 0 则需要将x + 1 ~ n的数都减小, (但我们没法减小, 可以先提前让答案减小, 看最后能否加回来)。
细节见于代码
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1e5 + 7;
ll a[N], f[N], T, n, k;
int main()
{
cin >> T;
while(T --)
{
ll ans = 0;
int flag = 1;
scanf("%lld%lld", &n, &k);
for(int i = 1; i <= n; i++)
{
scanf("%lld", a + i);
f[i] = a[i] - a[i - 1];
}
for(int i = 2; i <= n; i++)
{
if(f[i] == 0) continue;
if(f[i] < 0)
if(i + k - 1 <= n) f[i + k] += f[i], ans -= f[i], f[i] -= f[i];
else
{
flag = 0;
break;
}
else
{
if(i - k >= 1 && (i - 1) % k == 0) // 如果前i - 1个数是k的倍数则可以调整为f[i]大小
{
f[1] += f[i];
ans += f[i] * ((i - 1) / k);
f[i] -= f[i];
}
}
}
for(int i = 2; i <= n; i++)
if(f[i] != 0)
{
flag = 0;
break;
}
if(flag == 1) printf("%lld\n", ans);
else printf("-1\n");
}
}