暴力想法肯定是遍历一遍x的取值范围看看哪个最小,问题就是如何看哪个最小
一个直观的思路是,首先值的变化分为三种,一个是不变,一个是变一个,一个是变两个
不变就是相加为x,那么我们可以想到,能变一个就成说明,我至多变一个的取值范围要包括x,因此只要求一下取值范围就变成了覆盖问题
这种问题可以用差分解决
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=4e5+10; const int inf=0x3f3f3f3f; int cnt[N]; int s[N]; int a[N]; int main(){ ios::sync_with_stdio(0); int t; cin>>t; while(t--){ int i; int n,k; cin>>n>>k; for(i=1;i<=n;i++){ cin>>a[i]; } for(i=1;i<=n/2;i++) cnt[a[i]+a[n-i+1]]++; for(i=1;i<=n/2;i++){ int tmp1=min(a[i],a[n-i+1])+1; int tmp2=max(a[i],a[n-i+1])+k; s[tmp1]++,s[tmp2+1]--; } for(i=2;i<=2*k;i++) s[i]+=s[i-1]; int ans=inf; for(i=2;i<=2*k;i++){ int tmp=n/2-s[i]; ans=min(ans,s[i]-cnt[i]+tmp*2); } cout<<ans<<endl; for(i=1;i<=2*k+1;i++){ s[i]=0; cnt[i]=0; } } }