Варианты дерева Фенвика: различия между версиями
Перейти к навигации
Перейти к поиску
Ctrlalt (обсуждение | вклад) (Новая страница: «== Одномерное дерево Фенвика == int a[MAX_SIZE]; int alpha(int x) { int res = 0; for (int i = x; i >= 0; i = (i & (i + 1)) -…») |
Ctrlalt (обсуждение | вклад) |
||
Строка 66: | Строка 66: | ||
void modifyAlphas(int x, int y, int val) { | void modifyAlphas(int x, int y, int val) { | ||
for (int i = x; i < MAX_SIZE; i |= i + 1) | for (int i = x; i < MAX_SIZE; i |= i + 1) | ||
for (int | for (int j = x; j < MAX_SIZE; j |= j + 1) | ||
a[i][j] += val; | a[i][j] += val; | ||
} | } | ||
Строка 122: | Строка 122: | ||
modifyBetas(rx + 1, ry + 1, -val * ry); | modifyBetas(rx + 1, ry + 1, -val * ry); | ||
modifyAlphas(rx + 1, ry + 1, val * rx * ry); | modifyAlphas(rx + 1, ry + 1, val * rx * ry); | ||
} | } | ||
== Ссылки == | == Ссылки == |
Версия от 15:07, 14 ноября 2014
Одномерное дерево Фенвика
int a[MAX_SIZE]; int alpha(int x) { int res = 0; for (int i = x; i >= 0; i = (i & (i + 1)) - 1) res += a[i]; return res; } void modifyAlphas(int x, int val) { for (int i = x; i < MAX_SIZE; i |= i + 1) a[i] += val; }
Запрос суммы на отрезке, изменение отдельных элементов
alpha(x) — сумма элементов от 0-го до x-го.
int sum(int x) { return alpha(x); } void add(int x, int val) { modifyAlphas(x, val); }
Запрос значений отдельных элементов, изменение на отрезке
alpha(x) — значение x-го элемента.
int get(int x) { return alpha(x); } void add(int l, int r, int val) { modifyAlphas(l, val); modifyAlphas(r + 1, -val); }
Запрос суммы на отрезке, изменение на отрезке
beta(x) * x + alpha(x) — сумма элементов от 0-го до x-го.
int sum(int x) { return beta(x) * x + alpha(x); } void add(int l, int r, int val) { modifyBetas(l, val); modifyAlphas(l, val * (-l + 1)); modifyBetas(r + 1, -val); modifyAlphas(r + 1, val * r); }
Двумерное дерево Фенвика
int a[MAX_SIZE][MAX_SIZE]; int alpha(int x, int y) { int res = 0; for (int i = x; i >= 0; i = (i & (i + 1)) - 1) for (int j = y; j >= 0; j = (j & (j + 1)) - 1) res += a[i][j]; return res; } void modifyAlphas(int x, int y, int val) { for (int i = x; i < MAX_SIZE; i |= i + 1) for (int j = x; j < MAX_SIZE; j |= j + 1) a[i][j] += val; }
Запрос суммы на прямоугольнике, изменение отдельных элементов
alpha(x, y) — сумма элементов от (0; 0)-го до (x; y)-го.
int sum(int x, int y) { return alpha(x, y); } void add(int x, int y, int val) { modifyAlphas(x, y, val); }
Запрос значений отдельных элементов, изменение на прямоугольнике
alpha(x, y) — значение (x; y)-го элемента.
int get(int x, int y) { return alpha(x, y); } void add(int lx, int rx, int ly, int ry, int val) { modifyAlphas(lx, ly, val); modifyAlphas(lx, ry + 1, -val); modifyAlphas(rx + 1, ly, -val); modifyAlphas(rx + 1, ry + 1, val); }
Запрос суммы на прямоугольнике, изменение на прямоугольнике
delta(x, y) * x * y + gamma(x, y) * y + beta(x, y) * x + alpha(x, y) — сумма элементов от (0; 0)-го до (x; y)-го.
int sum(int x, int y) { return delta(x, y) * x * y + gamma(x, y) * y + beta(x, y) * x + alpha(x, y); } void add(int lx, int rx, int ly, int ry, int val) { modifyDeltas(lx, ly, val); modifyGammas(lx, ly, val * (-lx + 1)); modifyBetas(lx, ly, val * (-ly + 1)); modifyAlphas(lx, ly, val * (-lx + 1) * (-ly + 1)); modifyDeltas(lx, ry + 1, -val); modifyGammas(lx, ry + 1, -val * (-lx + 1)); modifyBetas(lx, ry + 1, val * ry); modifyAlphas(lx, ry + 1, val * (-lx + 1) * ry); modifyDeltas(rx + 1, ly, -val); modifyGammas(rx + 1, ly, val * rx); modifyBetas(rx + 1, ly, -val * (-ly + 1)); modifyAlphas(rx + 1, ly, val * rx * (-ly + 1)); modifyDeltas(rx + 1, ry + 1, val); modifyGammas(rx + 1, ry + 1, -val * rx); modifyBetas(rx + 1, ry + 1, -val * ry); modifyAlphas(rx + 1, ry + 1, val * rx * ry); }