RMQ problem может быть расширен следующим образом:Использование двоичных индексированные деревьев для расширения RMQ
Учитывая это массив целых чисел n
A
.
запроса (х, у): даны два целых числа 1 ≤ x
, y
≤ n
, найти минимум A[x], A[x+1], ... A[y]
;
обновление (х, у): дано целое число v
и 1 ≤ x
≤ n
делают A[x] = v
.
Эта проблема может быть решена в O(log n)
для обеих операций с использованием segment trees.
Это эффективное решение на бумаге, но на практике сегментные деревья содержат много накладных расходов, особенно если они реализованы рекурсивно.
Я знаю, что существует способ решить проблему в O(log^2 n)
для одного (или обоих, я не уверен) операций, используя двоичные индексированные деревья (можно найти больше ресурсов, но this и this, IMO, самые сжатые и исчерпывающие, соответственно). Это решение для значений n
, которые вписываются в память, на практике быстрее, потому что у BIT намного меньше накладных расходов.
Однако я не знаю, как структура BIT используется для выполнения данных операций. Я знаю только, как использовать его для запроса суммы интервала, например. Как я могу использовать его, чтобы найти минимум?
Если это помогает, у меня есть код, написанный другими, который делает то, о чем я прошу, но я не могу понять это. Вот один такой кусок кода:
int que(int l, int r) {
int p, q, m = 0;
for(p=r-(r&-r); l<=r; r=p, p-=p&-p) {
q = (p+1 >= l) ? T[r] : (p=r-1) + 1;
if(a[m] < a[q])
m = q;
}
return m;
}
void upd(int x) {
int y, z;
for(y = x; x <= N; x += x & -x)
if(T[x] == y) {
z = que(x-(x&-x) + 1, x-1);
T[x] = (a[z] > a[x]) ? z : x;
}
else
if(a[ T[x] ] < a[ y ])
T[x] = y;
}
В приведенном выше коде, T
инициализируется 0, a
является данный массив, N
его размер (они индексацию с 1 по какой-либо причине) и upd
вызывается в сначала для каждого значения чтения. До того, как upd
называется a[x] = v
.
Кроме того, p & -p
- это то же самое, что и p^(p & (p - 1))
в некоторых источниках BIT, и индексирование начинается с 1 с нулевым элементом, инициализированным до бесконечности.
Может ли кто-нибудь объяснить, как это работает, или как я могу решить данную проблему с помощью BIT?
'for (y = x; x <= N; x + = x & -x)' это глубоко. Кстати, что такое 'T []'? BTW2: Я не уверен, что это должно быть 'for (y = x; x
wildplasser
@wildplasser - этот первый 'for' на самом деле довольно стандартный для BIT. Кажется, что 'T', где фактически хранится информация BIT. Что касается 'N', то есть' n' в моей постановке задачи, я отредактирую это. – IVlad