D. Constant Palindrome Sum(差分)

D. Constant Palindrome Sum(差分好题)

题目传送门:

D. Constant Palindrome Sum

题目大意:

给你一个数组a,你可以将其中的每个元素改为[1,k]的任意数字。但是在修改后每对ai + an-i+1都为常数x。

思路:

假设我们另a1=ai , a2 = an-i+1
首先想到的是。
1.当x = a1 + a2时需要修改0个数
2.当x>=min(a1,a2)+1且x<=max(a1,a2)+k且x!=a1+a2时需要修改其中的一个数
3.其他则需要修改两个数。
最开始的想法当然是暴力,枚举每个x然后再枚举每个数,看需要修改几遍,然后求和取小,这样的时间的复杂度为nk,妥妥的T了。然后再看上面的性质,我们发现需要修改的数量是一个连续的区间。
即[2,min(a1,a2)+1) 需要修改两次 ,[min(a1,a2)+1,a1+a2) 需要修改一次,a1+a2需要修改0次,然后(a1+a2,max(a1,a2)+k]需要修改1次,(max(a1,a2)+k,2*k]需要修改两次。那么就可以用差分的性质了。

AC Code

#include
using namespace std;
const int N=2e5+10;
int a[N];
int ans[N*2];
int main()
{
     
    int t;
    scanf("%d",&t);
    while(t--)
    {
     
        int n,k;
        scanf("%d%d",&n,&k);
        memset(ans,0,sizeof(ans));
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        for(int i=1;i<=n/2;i++)
        {
     
            ans[2]+=2;
            int p=min(a[i],a[n-i+1])+1;
            ans[p]--;
            p=a[i]+a[n-i+1];
            ans[p]--;
            ans[p+1]++;
            p=max(a[i],a[n-i+1])+k;
            ans[p+1]++;
        }
        int res=1e9;
        int num=0;
        for(int i=2;i<=2*k;i++)
        {
     
            num=num+ans[i];
            res=min(num,res);
        }   
        printf("%d\n",res);
    }
    //system("pause");
    return 0;
}

你可能感兴趣的:(差分,Codeforces,差分,codeforces,思维)