Suma de prefijo diferencial

Suma de prefijo diferencial

Prefijo y operación

Si le doy una serie de números a1, a2, a3 ... an de longitud n, y luego doy m consultas, cada consulta da dos números L y R, y pide el número en el intervalo [L, R] ¿Qué Si alguien que nunca ha entendido la suma del prefijo ve esta pregunta, la idea puede ser que para m preguntas, atraviese el intervalo que da y calcule la respuesta cada vez. Este método es ciertamente cierto Sí, pero usando dos ciclos , la complejidad del tiempo llega a O (n * n). Si la cantidad de datos es un poco mayor, es posible que se agote el tiempo, y si usamos el método de suma de prefijos para hacerlo, podemos complicar el tiempo El grado se reduce a O (n + m), lo que ahorra mucho tiempo de cálculo.

int tr[1005] = {0};
for(int i = 1; i <= n; i++)
    tr[i] += tr[i - 1];

Entonces necesitas la suma de los números en el intervalo, puedes usar tr [R] -tr [L-1]

Diferencia

Darle una secuencia de números a1, a2, a3 ... an de longitud n, y requerir m operaciones en a [L] ~ a [R]:

Operación 1: agregue P a todos los elementos en una [L] ~ a [R]

Operación 2: Reste P de todos los elementos en a [L] ~ a [R]

Finalmente, se da una pregunta para encontrar la suma de los elementos en un [L] -a [R]?

¿Qué harías? Podrías pensar que recorro una [L] ~ a [R] cada vez para m operaciones, sumo P o resto P a los números en el intervalo y finalmente encuentro la suma del prefijo nuevamente. Así es, esto puede obtener la respuesta correcta, pero la complejidad del tiempo es tan alta como O (M * n + q). Para el rango de datos 1 <= n, m <= 1e5, es directamente tle, por lo que este método no es factible. En este momento, la diferencia es útil. Podemos usar otra matriz de diferencias br [] para almacenar cada paso de la operación, como agregar c a los elementos de [a, b] al mismo tiempo, luego podemos dejar br [a] + = c, br [b + 1] - = c, en este caso, si vuelve a encontrar la suma del prefijo, puede sumar c a todos los números del intervalo

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

int main()
{
    int tr[10005] = {0};
    int br[10005] = {0};//差分数组
    int n, m, a, b, c;
    int add = 0;
    cin>>n>>m;//n是数组个数,m是进行的操作次数
    for(int i = 1; i <= n; i++)
    {
        cin>>tr[i];
    }
    for(int i = 1; i <= m; i++)
    {
        cin>>a>>b>>c;//对[a,b]的元素进行加c
        br[a]+=c;//差分数组
        br[b + 1]-=c;
    }
    for(int i = 1; i <= n; i++)
    {
        add+=br[i];//add是一直在相加的
        tr[i] += tr[i - 1] + add;//求前缀和,同时加上add,即加上该位置的元素经过操作后加的数
    }
    cin>>a>>b;//输入所需输出的区间
    cout<<tr[b] - tr[a - 1];

    //cout<<ans;
}

ejemplo

Niuniu regando los árboles

Descripción del Título

Niuniu tiene ahora n árboles en el jardín, ordenados del primero al enésimo. Niuniu regará los árboles en una determinada sección de acuerdo con su estado de ánimo todos los días. Por ejemplo, si el intervalo de riego es [2,4] en un día determinado, Niuniu regará el segundo, tercer y cuarto árbol ese día. Los árboles crecerán después de ser regados Para simplificar el problema, asumimos que la altura de todos los árboles es 0 cm al principio. El árbol crecerá naturalmente 1 cm cada día, y cada vez que se riegue, crecerá 1 cm más en el día. Niuniu elige un intervalo [l, r] todos los días en m días para regar los árboles en este intervalo. Niuniu quiere saber cuántos árboles son impares en altura después de m días. ¿Puedes decirle a Niuniu?

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 返回m天后高度为奇数的树的数量
     * @param n int整型 
     * @param m int整型 
     * @param l int整型vector 
     * @param r int整型vector 
     * @return int整型
     */
    int oddnumber(int n, int m, vector<int>& l, vector<int>& r) {
        // write code here
        int  sum[200020] = {0};
        int ans = 0;
        for(int i = 0; i < m; i++)
        {
            sum[l[i]]++;
            sum[r[i] + 1]--;
        }
        for(int i = 1; i <= n; i++)
        {
            sum[i] += sum[i - 1];
        }
        for(int i = 1; i <= n; i++)
        {
            if((sum[i] + m) % 2 == 1)
                ans++;
        }
        return ans;
    }
};

Supongo que te gusta

Origin blog.csdn.net/weixin_51216553/article/details/111663775
Recomendado
Clasificación