CF-div3-636-D. Constant Palindrome| 静态区间修改 差分 贪心 分类讨论
思路
考虑最终修改后和为x,x的值到底是多少最优。
作分类讨论:
1.x在[2,mi] 一定要改两次 因为把把ai和an-i+1中最大的数改成1 也比x大; 所以把[2,mi]修改次数+2
2.x在[mx+k+1,2k] 一定要改两次 因为把ai和an-i+1中最大的数加k也到不了x;所以把[mx+k+1,2k]修改次数+2
3.x在[mi+1,mx+k] 且不等于 sum 可贪心只改一次就能该到x;所以把[mi+1,mx+k]修改次数+1
因为是静态区间修改,所以用差分数组即可,用线段树区间修改也行。
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 4e5+100;
ll a[maxn],delta[maxn];
int t;
int n,k;
void solve(){
cin>>n>>k;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=2*k+10;i++) delta[i] = 0;
for(int i=1;i<=n;i++){
if(i <= n/2){
ll sum = a[i] + a[n-i+1];
ll mx = max(a[i],a[n-i+1]);
ll mi = min(a[i],a[n-i+1]);
//1.x在[2,mi] 一定要改两次 因为把最大的改成1 也比x大
delta[2]+=2;
delta[mi+1]-=2;
//2.x在[mx+k+1,2*k] 一定要改两次 因为把最大的加k也到不了x
delta[mx+k+1]+=2;
delta[2*k+1]-=2;
//3.x在[mi+1,mx+k] 且不等于 sum 可贪心只改一次
delta[mi+1]++;
delta[mx+k+1]--;
delta[sum]--;
delta[sum+1]++;
}
}
ll ans = delta[2];
for(int i = 2;i<=2*k;i++){
delta[i] += delta[i-1];
ans = min(ans,delta[i]);
}
cout<<ans<<endl;
}
int main(){
cin>>t;
while(t--){
solve();
}
return 0;
}