Codeforces Round #636 (Div. 3) D( 差分 )

题目链接
在这里插入图片描述
大致题意:
给你长度为n的数组,n为偶数且1<=a[i]<=k;给你一种操作可将a[i]替换成[1,k]任意一个数,要你求最小操作次数使得满足:对于所有的1<=i<=n/2 都有a[i]+a[n-i+1]为一相同值。
解题报告:
我们可以用差分数组维护x值的最小操作次数;
sum=p[i]+p[n-i+1] , mi=min(p[i],p[n-i+1]) , mx=max(p[i],p[n-i+1])

分情况讨论:

  1. x∈[ 2,mi ] 两个值均要减小 故操作数+=2
  2. x∈[ mi+1,mx+k ] 此时只需更改mi即可 故操作数+=1
  3. x∈[ mx+k+1,2*k ] 两个值均要更改 故操作数+=2
  4. x==sum;之前讨论已将将其算进去了,需将其减去 故操作数-=1
#define first f
#define second s
#define ll long long
#define mp make_pair
#define pb push_back
#define pf push_front
#define lb lower_bound
#define ub upper_bound
#define sl(p) strlen(p)
#define SZ(p) p.size()
#define pii pair<int,int>
#include <bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
const int MOD=1e9+7;
const int maxn=2e5+5;
const int inf=0x3f3f3f3f;

int d[maxn<<1],p[maxn];

int main()
{
    int T,n,k;
    scanf("%d",&T);
    while(T--){
        mem(d,0);
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++)scanf("%d",&p[i]);
        for(int i=1;i<=n/2;i++){
            int sum=p[i]+p[n-i+1];
            int mi=min(p[i],p[n-i+1]),mx=max(p[i],p[n-i+1]);
            d[2]+=2;
            d[mi+1]--;
            d[mx+k+1]++;
            d[sum]--;
            d[sum+1]++;
        }
        int ans=inf,num=0;
        for(int i=2;i<=(k<<1);i++){
            ans=min(ans,num+=d[i]);
        }
        printf("%d\n",ans);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值