Update

void update(int i, int delta) {
  while (i <= n) {
    bit[i] += delta;
    i += i & -i;  // add lowest set bit
  }
}
Advertisement

Prefix sum

long query(int i) {
  long sum = 0;
  while (i > 0) {
    sum += bit[i];
    i -= i & -i;  // strip lowest set bit
  }
  return sum;
}
Advertisement

Range sum

query(r) - query(l - 1).

Why it works

Each index handles a specific range of prefixes based on its lowest set bit. Bit tricks encode which range.