Suma de prefijo unidimensional

Suma de prefijo unidimensional

La función del prefijo y la matriz es cambiar la consulta del intervalo por la consulta del final del intervalo.
A menudo se utiliza para calcular la suma del elemento L al elemento R de la secuencia, es decir, el problema de suma de intervalos de la secuencia.

Prefijo y-
ejemplo de prefixSum :

Suponga que la matriz original nums [] = {0,5,6,7,8}; por
lo tanto, puede ser una matriz de prefijo obtenido recursivamente y la matriz prefixSums [] = {5,11,18,26};
Nota: el prefijo y subíndices de matriz Almacenar valores a partir de 1

El proceso de recursividad es el siguiente:
prefixSums [0] = nums [0] = 0;

prefixSums [1] = nums [0] + nums [1] = prefixSums [0] + nums [1] = 5;

prefixSums [2] = nums [0] + nums [1] + nums [2] = prefixSums [1] + nums [2] = 11;

prefixSums [3] = nums [0] + nums [1] + nums [2] + nums [3] = prefixSums [2] + nums [3] = 18;

prefixSums [4] = nums [0] + nums [1] + nums [2] + nums [3] + nums [4] = prefixSums [3] + nums [4] = 26;

Resumido de lo anterior:
prefixSums [i] = prefixSum [i-1] + nums [i];

¡Atención! ! ! :
Utilice prefixSum [R] -prefixSum [L-1] para calcular la suma del elemento Lth al elemento de suma Rth

Implementación de código de prefijo y matriz:

#include <iostream>

using namespace std;

const int N = 10010;
int nums[N];//原数组
int prefixSums[N];//前缀和数组

int main()
{
    
    
    int n;
    scanf("%d",&n);
    
    //prefixSums[i - 1]的下标从0开始,所以i要从1开始
    for (int i = 1;i <= n;i++)
    {
    
    
        scanf("%d",&nums[i]);
        
        //核心代码
        prefixSums[i] = prefixSums[i - 1] + nums[i];
    }
    for (int i = 1;i <= n;i++) printf("%d ",prefixSums[i]);
    return 0;
}

Ejemplo:
Enlace a la pregunta original.
Hay N números enteros positivos colocados en la matriz A. Ahora debe encontrar y generar dicha matriz:
el i-ésimo número de esta matriz es el primer número de la matriz A en la i-ésima número de matriz A La suma.
Ingrese
1 entero positivo en la primera línea: N, el rango de N es [1, 100].
N números enteros positivos en la segunda línea: el rango es [1, 10000].
Salida
N enteros positivos.
Entrada de muestra
6
2 6 1 9 7 3
Salida de muestra
2 8 9 18 25 28

Código AC:

#include <cstdio>
#include <iostream>

using namespace std;

const int N = 110;
int prefixSum[N];//定义前缀和数组
int a[N];//定义原数组

int main()
{
    
    
    int n;
    scanf("%d",&n);
    
    //统一从1开始计数
    for (int i = 1;i <= n;i++)
    {
    
    
        scanf("%d",&a[i]);
        prefixSum[i] = prefixSum[i - 1] + a[i];
    }
    for (int j = 1;j <= n;j++) printf("%d ",prefixSum[j]);
    return 0;
}

Pregunta de ejemplo 2
Enlace a la pregunta original
Descripción del título
Dada una matriz de longitud n, encuentre la suma de los elementos en un cierto intervalo [L, R] de la matriz arr.
Ingrese
un número n en la primera línea, indicando la longitud de la matriz.
La segunda línea contiene n enteros y cada entero está separado por un espacio para indicar los datos de la matriz.
Un número m en la tercera línea indica el número de operaciones a realizar.
Comenzando desde la cuarta línea hasta la línea m + 3, cada línea incluye dos matrices L y R, que representan el rango de matriz de la operación.
La salida tiene un
total de m líneas, cada línea tiene un número entero, que representa la suma de los elementos de intervalo correspondientes.
Entrada Copia de muestra
10
5 2 -3 1 -5 10 150 300 1200 93
4
1 3
2 5
1 8
1 10
Ejemplo de salida Copia
4
-5
460
1753
prontas
[rango de datos]
1 ⩽ m ⩽ n ⩽10 ^ 5
- 10 ^ 12 ⩽ ai ⩽10 ^ 12
1 ⩽ R ⩽ L⩽10 ^ 5

#include <iostream>
#include <cstdio>
 
using namespace std;
 
const int N = 100010;
long long a[N];//int 最大值是2147483647,而−10^12⩽ai⩽10^12
 
int main()
{
    
    
    int n;
    scanf("%d",&n);
    for (int i = 1;i <= n;i++) scanf("%lld",&a[i]);
     
    int m;
    scanf("%d",&m);
    while (m--)
    {
    
    
        long long int ans = 0;
        int l,r;
        scanf("%d%d",&l,&r);
        for (int j = l;j <= r;j++) ans += a[j];
        printf("%lld\n",ans);
    }
    return 0;
}

Nota: El algoritmo ingenuo anterior puede ser lógicamente AC, pero no sé por qué. . .

Inserte la descripción de la imagen aquí
El grandullón que preguntó a ACM no lo vio y finalmente cambié el código a este. Quien encuentre un código que pueda ser A puede corregirme.

Después de un tiempo, continúe escribiendo más en el blog.
Buen chico, resulta que el código está escalonado con el número de pregunta. Es tan estúpido abrir la puerta a los estúpidos. El siguiente es el prefijo, el código y la idea del ejemplo anterior

由 题 意 得
ans = a [l] + a [l + 1] +…… + a [r - 1] + a [r]
= (a [0] + a [1] + a [2] +… … + A [l - 1]) + a [l] + a [l + 1] +…… + a [r - 1] + a [r] - (a [0] + a [1] + a [ 2] +…… + a [l - 1])
观察 得
(a [0] + a [1] + a [2] +…… + a [l - 1]) + a [l] + a [l + 1] +…… + a [r - 1] + a [r] = prefixSum [r];
(a [0] + a [1] + a [2] +…… + a [l - 1]) = prefixSum [l - 1];

Es decir, prefijo y código central:
ans = prefixSum [r] -prefixSum [l-1]

#include <cstdio>
#include <iostream>

using namespace std;

const int N = 100010;
long long prefixSum[N];//前缀和数组
long long a[N];//原数组


int main()
{
    
    
    int n;
    scanf("%d",&n);
    
    //从1开始,数组下标就刚好是第几位数
    for (int i = 1;i <= n;i++)
    {
    
    
        scanf("%lld",&a[i]);
        
        //前缀和数组
        prefixSum[i] = prefixSum[i - 1] + a[i];
    }
    
    int m;
    scanf("%d",&m);
    for (int i = 1;i <= m;i++)
    {
    
    
        int l,r;
        long long ans = 0;
        scanf("%d%d",&l,&r);
        ans = prefixSum[r] - prefixSum[l - 1];
        printf("%lld\n",ans);
    }
    
    return 0;
}

Por supuesto, en comparación con el algoritmo ingenuo anterior, la suma del prefijo optimiza la complejidad del tiempo desde el nivel O (n ^ 2) al nivel O (n)

Supongo que te gusta

Origin blog.csdn.net/smallrain6/article/details/112757186
Recomendado
Clasificación