CF1343D Constant Palindrome Sum(差分)

暴力想法肯定是遍历一遍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;
        }
 
    }
}
View Code

 

posted @ 2020-04-29 14:55  朝暮不思  阅读(215)  评论(0编辑  收藏  举报