D. Constant Palindrome Sum
题目
给定n个数,每个数都为偶数,并且每个数∈[1, k]。修改其中的数字,使得满足以下条件:
- 每个数∈[1, k]
- a[i]+a[n-i+1]=x
思路
对于每一个i (i<n/2),假设让a = a[i]、b=a[n-i+1],要使a+b等于某个定值x,我们可以修改的个数的可能性为3种,即不修改、修改1个、修改两个。
- 修改个数为2,得到的定值区间范围为 [2, min(a, b)+1-1]
- 修改个数为1,得到的定值区间范围为 [min(a, b)+1, a+b-1]
- 修改个数为0,得到的值为 a+b
- 修改个数为1,得到的定值区间范围为 [a+b+1, max(a, b)+k]
- 修改个数为2,得到的定值区间范围为 [max(a, b)+k+1, n]
对于以上情况,操作数的变化如下:
- d[2] += 2
d[min(a, b)+1] -= 2 - d[min(a, b)+1]++
d[a+b]- - - d[a+b] 不做变化
- d[a+b+1]++
d[max(a, b)+k+1]- - - d[max(a, b)+k+1] += 2
d[2*k+1] -= 2
代码
#include <iostream>
#include <climits>
using namespace std;
const int MAXN = 4e5 + 5;
const int INF = INT_MAX;
int a[MAXN];
int d[MAXN];
int main(){
int t;
cin >> t;
while(t--){
int n, k;
cin >> n >> k;
for(int i=0; i<n; i++){
cin >> a[i];
}
for(int i=2; i<=2*k; i++){
d[i] = 0;
}
for(int i=0; i<n/2; i++){
int x = min(a[i], a[n-i-1]);
int y = max(a[i], a[n-i-1]);
d[2] += 2;
d[x+1]--;
d[x+y]--;
d[x+y+1]++;
d[y+k+1]++;
}
int cur = 0, ans = INF;
for(int i=2; i<=2*k; i++){
cur += d[i];
ans = min(ans, cur);
}
cout << ans << endl;
}
return 0;
}