Escrito por Lúcio Figueiredo
A técnica de somas de prefixo é uma das mais recorrentes em olimpíadas de informática. Neste material, vamos definir as somas de prefixo e apresentar algumas de suas aplicações.
Motivação Inicial
Imagine o seguinte problema: Nos é dado um vetor de tamanho
e
perguntas (ou queries). Cada query consiste de dois índices
e
. Para cada uma dessas queries, devemos imprimir como resposta a soma dos números de
com indíces entre
e
; ou seja, a resposta de cada query
é a soma
.
Para resolver o problema, podemos utilizar uma solução bem simples: basta que percorramos o vetor com um loop for indo desde o índice até o índice
, armazenando a soma dos valores em uma variável de resposta. Porém, note que a complexidade desta solução é
para cada query; logo, a complexidade total da solução é
. Para valores de
e
indo até
, a solução realizará
operações, o que não é eficiente. Como podemos resolver o problema com uma complexidade melhor?
Somas de Prefixo
Um prefixo de um vetor é definido como um intervalo contínuo deste vetor que começa do seu primeiro índice. Em particular, o -ésimo prefixo do vetor
é o intervalo contínuo de elementos
. Já uma soma de prefixo de um vetor é simplesmente a soma dos elementos de um prefixo. Ou seja, a
-ésima soma de prefixo do vetor
, denominada por
, é igual à soma
.
Na imagem acima, podemos observar um exemplo de vetor e cada uma de suas somas de prefixo. Para calcular as somas de prefixo
de um vetor
, podemos usar o seguinte simples algoritmo, com complexidade
:
- Inicialmente, fazemos
;
- Em seguida, iteramos por cada índice
do vetor em sequência;
- Para calcular
, basta fazer
. Ou seja, a soma dos
primeiros valores de
é igual à soma dos
primeiros valores somada ao valor do
-ésimo elemento.
Somas de intervalos em 
Mas como somas de prefixo nos ajudam a encontrar a soma de um intervalo qualquer? Observe que, utilizando somas de prefixo, conseguimos encontrar a soma do intervalo
- este valor é exatamente a soma
. Porém, esta soma inclui mais elementos do vetor do que o desejado; especificamente, a soma de prefixo
soma todos os elementos no intervalo
e, também, todos os elementos em
. Portanto, temos a seguinte relação:
Porém, note que é exatamente igual a
! Logo, temos que
Ou seja, a soma do intervalo é igual ao valor
. A imagem abaixo ilustra este fato de maneira intuitiva:
Portanto, utilizando somas de prefixos, conseguimos calcular somas de intervalos quaisquer de um vetor com complexidade : basta imprimir o valor
.
O código a seguir implementa a solução para o problema original indicada acima, utilizando somas de prefixos:
Problemas para praticar:
A lista a seguir contém alguns problemas que utilizam as ideias exploaradas na aula. Bons treinos!