Бинарное индексированное дерево для префиксных запросов и обновлений за O(log n)
n = int(input())
A = list(map(int, input().split()))
F = [0] * (n + 1)
def get(r):
z = 0
while r > 0:
z += F[r]
r -= r & -r
return z
def add(p, z):
while p <= n:
F[p] += z
p += p & -p
def upd(p, z):
d = z - A[p - 1]
A[p - 1] = z
add(p, d)
def tree():
for i in range(1, n + 1):
add(i, A[i - 1])
tree()
m = int(input())
for _ in range(m):
s = input().split()
if s[0] == "s":
l, r = int(s[1]), int(s[2])
print(get(r) - get(l - 1), end=" ")
elif s[0] == "u":
p, z = int(s[1]), int(s[2])
upd(p, z)
else:
p, z = int(s[1]), int(s[2])
add(p, z)
#include <bits/stdc++.h>
using namespace std;
int n;
vector<int> A, F;
int get(int r) {
int z = 0;
while (r > 0) {
z += F[r];
r -= r & -r;
}
return z;
}
void add(int p, int z) {
while (p <= n) {
F[p] += z;
p += p & -p;
}
}
void upd(int p, int z) {
int d = z - A[p - 1];
A[p - 1] = z;
add(p, d);
}
void build() {
for (int i = 1; i <= n; i++) {
add(i, A[i - 1]);
}
}
int main() {
cin >> n;
A.resize(n);
F.assign(n + 1, 0);
for (int i = 0; i < n; i++) {
cin >> A[i];
}
build();
int m;
cin >> m;
for (int i = 0; i < m; i++) {
string s;
cin >> s;
if (s == "s") {
int l, r;
cin >> l >> r;
cout << get(r) - get(l - 1) << " ";
} else if (s == "u") {
int p, z;
cin >> p >> z;
upd(p, z);
} else {
int p, z;
cin >> p >> z;
add(p, z);
}
}
return 0;
}
Дерево Фенвика (Binary Indexed Tree) — это структура данных, которая позволяет выполнять два типа операций за O(log n):
Каждый индекс i в дереве Фенвика хранит сумму не одного элемента, а диапазона элементов. Размер диапазона определяется младшим единичным битом числа i (операция i & -i).
Сложность операций: O(log n) — количество итераций равно количеству битов в числе.
Пространственная сложность: O(n) — массив размера n+1.
Построение дерева:
Запросы (m — количество запросов):
s l r — сумма на отрезке [l, r]u p z — обновление элемента p (замена на z)a p z — добавление z к элементу p5
1 2 3 4 5
4
s 1 3
a 2 2
s 1 3
u 3 10
s 1 5
Вывод: 6 8 21
(сумма [1,3]=6, после добавления A[2]+=2 → массив [1,4,3,4,5], сумма[1,3]=8, после замены A[3]=10 → массив [1,4,10,4,5], сумма[1,5]=24)
Введите массив и выполните запросы: