# A. Cola de alineación equilibrada (pregunta de plantilla rmq)

tema


tren de pensamiento

Se recomienda consultar primero la explicación detallada del problema rmq .

Obviamente, esta pregunta está destinada a seguirle una serie de números y brindarle múltiples consultas, preguntando sobre la diferencia entre los valores máximo y mínimo en el intervalo.

Si realiza una enumeración violenta, obviamente expirará el tiempo de espera, así que use el algoritmo st para resolverlo.

Vamos a crear dos contenidos de preprocesamiento RMQ para tratar con el valor máximo y el valor mínimo respectivamente.

Cree un mx[i][j] para representar el valor máximo en el intervalo que comienza desde i y una longitud de 2^j, y mn[i][j] para representar el valor mínimo en el intervalo que comienza desde i y una longitud de 2^j .

Según la idea de duplicar, un intervalo con una longitud de 2 ^ j se puede dividir en dos subintervalos con una longitud de 2 ^ (j-1), y luego se puede encontrar el valor máximo de los dos subintervalos. Por lo tanto, durante el preprocesamiento, el intervalo se divide en dos partes uniformemente desde el medio (no importa si hay superposición en el medio y no afecta el valor máximo), y el número de elementos en cada parte es exactamente 2^j-1, es decir, la ecuación de transición de estado es:

mx[j][i] = máx(mx[j][i - 1],mx[j + s[i - 1]][i - 1])

mn[j][i] = min(mn[j][i - 1],mn[j + s[i - 1]][i - 1])

(s[i] representa potencia 2^i)

Si F [i, j] representa el valor máximo del intervalo [i, i+2^j-1] y la longitud del intervalo es 2^j, ¿cuál es el rango de valores de i y j?

Si la longitud de la matriz es n y la longitud máxima del intervalo es 2^r≤n<2^(r+1), entonces r=⌊log2n⌋, por ejemplo, k=3 cuando n=8 y k= 3 cuando n=10. En el programa, r=log2(n), i de 1~i<=r, j de 1~s[i]+j-1<=n (porque i representa la longitud del intervalo y j representa el punto inicial posición del intervalo)

Código de preprocesamiento:

void pre()
{
  int r = log2(n);
  for(int i = 1; i <= r; i++)
    for(int j = 1; s[i] + j - 1 <= n; j++)
    {
      mx[j][i] = max(mx[j][i - 1],mx[j + s[i - 1]][i - 1]);
      mn[j][i] = min(mn[j][i - 1],mn[j + s[i - 1]][i - 1]);
    }
}

Después del preprocesamiento, es hora de comenzar a realizar consultas.

Si consulta los valores máximo y mínimo del intervalo [l, r], primero calcule el valor k, que es el mismo que el método de cálculo anterior, y la longitud del intervalo es r-l + 1.

2^k≤r-l+1<2^(k+1), entonces k=log2(r-l+1).

Si la longitud del intervalo de consulta es mayor o igual a 2 ^ k y menor que 2 ^ (k + 1), entonces, de acuerdo con la idea de la multiplicación, el intervalo de consulta se puede dividir en dos intervalos de consulta y el valor máximo de Se pueden tomar los dos intervalos. Los dos intervalos son 2^k números hacia atrás desde ly 2^k números hacia adelante desde r. Estos dos intervalos pueden superponerse, pero no tienen ningún efecto en encontrar el valor máximo.

查询代码:

int f(int x,int y)
{
  int r = log2(y - x + 1);
  int t1 = max(mx[x][r],mx[y - s[r] + 1][r]);
  int t2 = min(mn[x][r],mn[y - s[r] + 1][r]);
  return t1 - t2;
}

整体代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
int t,n,q,a[1000001],mx[1000001][20],mn[1000001][20],s[1000001],x,y;
void pre()
{
  int r = log2(n);
  for(int i = 1; i <= r; i++)
    for(int j = 1; s[i] + j - 1 <= n; j++)
    {
      mx[j][i] = max(mx[j][i - 1],mx[j + s[i - 1]][i - 1]);
      mn[j][i] = min(mn[j][i - 1],mn[j + s[i - 1]][i - 1]);
    }
}
int f(int x,int y)
{
  int r = log2(y - x + 1);
  int t1 = max(mx[x][r],mx[y - s[r] + 1][r]);//最大
  int t2 = min(mn[x][r],mn[y - s[r] + 1][r]);//最小
  return t1 - t2;//差
}
signed main()
{
  s[0] = 1;
  for(int i = 1; i <= 20; i++) s[i] = s[i - 1] * 2;//s[i]代表2^i次方
  scanf("%lld%lld",&n,&q);
  for(int i = 1; i <= n; i++)
  {
    scanf("%lld",&t);
    mx[i][0] = mn[i][0] = t;//初始化,从第i个位置向后延2^0位的最大值和最小值都是输入的第i个位置上的数
  }
  pre();//预处理
  for(int i = 1; i <= q; i++)
  {
    scanf("%lld%lld",&x,&y);
    printf("%lld\n",f(x,y));//查询
  }
  return 0;
}

Supongo que te gusta

Origin blog.csdn.net/weq2011/article/details/128767164
Recomendado
Clasificación