Titulo
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;
}