题意:
给定一个长度为 n n n 的数列, n n n 为偶数,保证每个元素在 [ 1 , k ] [1 , k] [1,k] 之间,每次操作可以把某个位置的数字变成 [ 1 , k ] [ 1 , k ] [1,k] 内的任意数字,要求让这个数列满足:对于所有的 i ∈ [ 1 , n / 2 ] , a i + a n − i + 1 i∈[1 ,n/2], a_i + a_{n-i+1} i∈[1,n/2],ai+an−i+1 是一个定值,求最少的操作次数。
差分数组维护取某个值为定值时所需要的最少操作次数,每次取一组 a i a_i ai 和 a n − i + 1 a_{n-i+1} an−i+1 处理,令 s u m = a i + a n − i + 1 , m a x n = m a x ( a i , a n − i + 1 ) , m i n n = m i n ( a i , a n − i + 1 ) sum = a_i+a_{n-i+1} ,maxn=max(a_i,a_{n-i+1}) ,minn=min(a_i,a_{n-i+1}) sum=ai+an−i+1,maxn=max(ai,an−i+1),minn=min(ai,an−i+1)
分类讨论:
- 如果定值在 [ 2 , m i n n ] [2,minn] [2,minn] 之间,此时这两个数都需要更改。这段区间的操作数 + 2 +2 +2。
- 如果定值在 [ m a x n + k + 1 , 2 ∗ k ] [maxn+k+1,2*k] [maxn+k+1,2∗k] 之间,此时这两个数都需要更改,这段区间的操作数 + 2 +2 +2 。
- 如果定值在 [ m i n n + 1 , m a x n + k ] [minn+ 1,maxn+k] [minn+1,maxn+k] 之间且不等于 s u m sum sum ,能够做到只改变其中一个数就使得和等于定值。这个范围内操作数+1.
- 特殊处理,如果定值等于sum,不需要更改任何一个数,所以这个点的操作数不需要增加。
AC代码:
const int N = 2e5 + 10;
int n, k;
int ans, sum, res;
int minn, maxn;
int a[N], b[N << 1];
int main()
{
int t;
sd(t);
while (t--)
{
sdd(n, k);
mem(b, 0);
rep(i, 1, n)
{
sd(a[i]);
if (i > n / 2)
{
sum = a[i] + a[n - i + 1];
minn = min(a[i], a[n - i + 1]);
maxn = max(a[i], a[n - i + 1]);
b[2] += 2;
b[minn + 1]--;
b[maxn + k + 1]++;
b[sum]--;
b[sum + 1]++;
}
}
ans = b[2];
rep(i, 3, 2 * k)
{
b[i] += b[i - 1];
ans = min(b[i], ans);
}
pd(ans);
}
return 0;
}