Executando verificação de segurança...
1

O que é prefix sum?

Imagina que você tem um array gigante com milhares de números
(ex: dados de vendas diárias de um ano).

Agora, você precisa responder perguntas como:

  1. "Qual foi o total de vendas entre o dia 15 e o dia 45?"
    ou
  2. "E entre o dia 100 e o 200?"

Mas e se seu software atende milhares de empresas e você precisar responder perguntas como estas, milhares de vezes?

A forma mais direta seria usar um loop para cada pergunta, somando os valores um por um.

Mas se tiver milhares dessas consultas, o programa vai ficar muito lento!

texto

O que é a Soma Acumulada (Prefix Sum)?

A ideia é simples: antes de precisar responder

"Qual foi o total de vendas entre o dia 15 e o dia 45?",

você cria um novo array (vamos chamá-lo de presum) que "pré-calcula" as somas.

Cada posição ( i ) desse novo array presum vai guardar a soma de todos os elementos antecedentes do array original, do início (índice 0) até a posição i.

Ou seja, cada posição do presum guarda quanto você já somou até aquele ponto em relação ao array original.

Exemplo:

Array Original: [10, 5, 8, 2, 7]

Array presum (Soma Acumulada):

    presum[0] = 10

    presum[1] = 10 + 5 = 15

    presum[2] = 15 + 8 = 23

    presum[3] = 23 + 2 = 25

    presum[4] = 25 + 7 = 32

presum final: [10, 15, 23, 25, 32]

A Mágica da Subtração

Agora vem a parte legal.

Como usamos isso para achar a soma de uma "fatia" (um range)?

Digamos que queremos a soma do índice 1 ao 2 de [5, 8, 2].

array.values = [5, 8, 2]

array.presum = [5, 13, 15]

Nosso startRange é 1 e nosso finalRange é 2.

1. Pegue a soma total ATÉ o final do seu intervalo do presum.

O nosso finalRange é 2.

Se olharmos no array.presum[2] , o valor é 15.

Esse número 15 representa a soma de TUDO desde o início (índice 0) até o índice 2 (finalRange).

array.presum[2] = (5 + 8 + 2) = 15

vou chamar esse valor de 15 de "ateOndeEuQuero"

ateOndeEuQuero = array.presum[2]

2. Descubra a parte que você NÃO quer.

ateOndeEuQuero é quase o que queremos,
mas ele inclui coisas antes do nosso startRange.

Nós só queremos começar do índice 1 (startRange).

A parte que não queremos é tudo o que vem antes do índice 1.

Neste caso, é apenas o índice 0 (o valor 5).

3. Onde achar a soma da parte que você NÃO quer?

A soma de tudo que vem antes do nosso startRange (índice 1) já está calculada!

Ela está guardada no presum na posição array.presum[ 0 ] .

Ou seja,

array.presum[ startRange - 1 ],

que é array.presum[0]. O valor é 5.

vou chamar de oQueEuNaoQuero

oQueEuNaoQuero = array.presum[ startRange - 1]

4. Pegue o total e só tire o que você não quer!

Agora é só subtrair o que você não quer (5) do total que você pegou (15).

apenasOqueEuQuero = ateOndeEuQuero - oQueEuNaoQuero

apenasOqueEuQuero = 15 - 5 = 10

Vamos checar:

a soma de [-, 8, 2] é 8 + 2 = 10. Funcionou!


arr.values = [5, 8, 2]

array.presum = [5, 13, 15]

startRange = 1

finalRange = 2

ateOndeEuQuero = array.presum[ finalRange ] 

oQueEuNaoQuero = array.presum[ startRange - 1 ]

apenasValorQueEuQuero = ateOndeEuQuero - oQueEuNaoQuero

Operamos com as posições desejadas no array de prefixos, esse é o grande poder, já lidamos com as somas précalculadas para obter a fatia de soma que queremos.

É obvio que nesse caso não fez muito sentido fazer tudo isso, era só a soma de dois valores.

Conclusão

Nem sempre vamos precisar de soma de intervalos, mas quando precisarmos, já vão estar prontas.
Podemos atualizar o array preSum sempre que os valores mudam, ou forem incrementados (se for o caso de uma lista).


Criação do array preSum

Criar o array preSum exige somar todos os elementos uma vez, um após o outro:

Você percorre o array original uma única vez, então o tempo total é proporcional ao tamanho do array — ou seja, O(n).


Consultas no preSum

Você só faz duas consultas diretas e uma subtração:

  • Cada uma dessas operações é instantânea (acesso direto a índice de array + subtração).
  • Elas não dependem do tamanho do array, nem do tamanho do intervalo.

Por isso, o tempo de execução é constante — O(1).


Ao gastar um tempinho no início para criar o array preSum um processo O(n)
você ganha o poder de responder qualquer soma de "fatias" em um tempo O(1).

⚠️ Mas atenção:
É importante perceber que calcular um presum ira consumir o dobro de mémoria do array original, e só fara sentido se tiver muitas requisições como essas.

Use presum em casos que os dados não mudam (são estáticos).

Mudam Raramente (Ex: Análise de dados históricos):
✅O Prefix Sum é a ferramenta ideal.

Mudam Sempre (Ex: Sistema de vendas ao vivo):
❌O Prefix Sum básico é ineficiente.

texto

Carregando publicação patrocinada...