题目链接
题意:给你一个初始数组A,你每次都可以选择数组中的一个数把它变成【1,k】中的任何一个数,要求你最终把数组A变成所有Ai和An-i+1加起来都恒等于x,问最小操作数。
思路:一开始确实没往差分方向写,一直想着如何用数据结构优化,结果就gg,还是太菜了嘤嘤嘤。
我们首先还是要思考的是最终肯定是要变成一个x的,而将Ai+An-i+1=x的操作对于每个i来说要么不操作,要么操作一个,要么i和n-i+1都操作,于是我们先假设所有的操作都是i和n-i+1也就是2,那么对于每一对Ai+Ai-1来说,l=min(a[i],a[n-i+1])+1,r=max(a[i],a[n-i+1])+k,只要是这个区间【l,r】里的x,Ai和An-i+1都只要选一个来操作就可以了,同时对于x==Ai+An-i+1来说就不需要操作了,用差分维护一下,最后看那个x的次数最小。
#include<bits/stdc++.h>
using namespace std;
const int maxn =2e5+1;
typedef long long ll;
int T,n,k,a[maxn],d[maxn<<1];
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d %d",&n,&k);
for(int i=1;i<=n;++i) scanf("%d",&a[i]);
for(int i=0;i<=2*k;++i) d[i]=0;
for(int i=1;i<=n/2;++i)
{
int l=min(a[i],a[n-i+1])+1,r=max(a[i],a[n-i+1])+k;
d[1]+=2,d[2*k+1]-=2;
d[l]--,d[r+1]++;
d[a[i]+a[n-i+1]]--,d[a[i]+a[n-i+1]+1]++;
}
int ans=1e9;
for(int i=1;i<=2*k;++i) d[i]+=d[i-1],ans=min(ans,d[i]);
printf("%d\n",ans);
}
}