Codeforces 1343D-Suma constante de palíndromo (matriz diferencial)


Titulo

Problema




Titulo

Dada una secuencia de longitud n, n es un número par, asegurando que cada elemento esté entre [1, k]

Cada operación puede cambiar el número en una determinada posición a cualquier número en [1, k]

Es necesario satisfacer esta secuencia: para todo i ∈ [1, n / 2], a [i] + a [n-i + 1] es un valor fijo

Pregunte la menor cantidad de operaciones




Ideas para resolver problemas

La matriz de diferencia mantiene el número mínimo de operaciones requeridas para tomar un cierto valor como un valor fijo

Deje que la matriz de diferencia sea delta

Tome un conjunto de [i] y [n-i + 1] a la vez

Hacer sum = a[i]+a[n-i+1] , maxn=max(a[i],a[n-i+1]) , minn=min(a[i],a[n-i+1])

Discusión de clasificación:

  1. Si el valor fijo x está entre [2, minn] , incluso si el número mayor se cambia a 1, la suma es mayor que x, lo que indica que ambos números deben cambiarse en este momento, por lo que los operandos en este intervalo + 2

  2. Si el valor fijo x está entre [maxn + k + 1,2 * k] , incluso si el número más pequeño se cambia a k, la suma es menor que x, lo que indica que ambos números deben cambiarse en este momento, por lo que esto Operando de intervalo de segmento +2

  En tercer lugar, si el valor de x en [Minn + 1, maxN + k ] entre y no es igual a SUM , uno puede hacer para cambiar sólo el número que es igual a x, por lo que esta gama de operando 1

  Cuarto, tratamiento especial, si el valor fijo x es igual a la suma , no hay necesidad de cambiar ningún número, por lo que el operando en este punto no necesita aumentar

En resumen, para la etiqueta de la matriz de diferencias, podemos obtener:

delta[2]+=2;
delta[minn+1]-=2;
//讨论 1
delta[maxn+k+1]+=2;
delta[2*k+1]-=2;
//讨论 2
delta[minn+1]++;
delta[maxn+k+1]--;
delta[sum]--;
delta[sum+1]++;//因为上面两步把sum位置加上了1,所以这里减去1
//讨论 3、4

Para la posición 2 * k + 1, es el final de la marca de matriz de diferencia, puede elegir no procesar

Así resuelto:

delta[2]+=2;
delta[minn+1]--;
delta[maxn+k+1]++;
delta[sum]--;
delta[sum+1]++;

Finalmente, comience desde la posición 2 a 2 * k para procesar la matriz de diferencia una vez

ans=delta[2];
for(int i=3;i<=2*k;i++)
{
    delta[i]+=delta[i-1];
    ans=min(delta[i],ans);
}



Programa completo

(62ms / 1000ms)

#include<bits/stdc++.h>
using namespace std;

int ar[200050],delta[400050]; //差分数组开2*k的空间

void solve()
{
    int n,k,sum,minn,maxn,ans;

    cin>>n>>k;
    memset(delta,0,(2*k+10)*sizeof(int)); //初始化到2*k即可(稍大)

    for(int i=1;i<=n;i++)
    {
        cin>>ar[i];
        if(i>n/2)
        {
            sum=ar[i]+ar[n-i+1];
            minn=min(ar[i],ar[n-i+1]);
            maxn=sum-minn;

            delta[2]+=2;
            delta[minn+1]--;
            delta[maxn+k+1]++;
            delta[sum]--;
            delta[sum+1]++;
        }
    }

    ans=delta[2];
    for(int i=3;i<=2*k;i++)
    {
        delta[i]+=delta[i-1];
        ans=min(delta[i],ans);
    }

    cout<<ans<<'\n';
}

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    int T;cin>>T;
    for(int t=1;t<=T;t++)
        solve();
    return 0;
}

Supongo que te gusta

Origin www.cnblogs.com/stelayuri/p/12749332.html
Recomendado
Clasificación