Я недавно начал изучать дерево Фенвика для ответа на проблему с диапазонными запросами. Но я запутался в 2 типах обработки запросов:
Сначала я предварительно обработал свой ввод и построил для него дерево Фенвика, а затем вычислял ответ для каждого запроса один за другим.
Построение и ответ на запросы выполняются одновременно. Я отвечаю на вопросы и строю свое дерево Фенвика.
И я обнаружил проблему, которая спрашивает: количество различных элементов в [L, R] для данного массива. Дан массив запросов вида [L, R].
Теперь в этой задаче я сначала строю дерево, а затем отвечаю на запросы один за другим. Я получил неправильный ответ на многие вопросы. Но когда я сортирую запросы по их R-значению и обрабатываю запрос одновременно со строительным деревом, я получаю правильный ответ.
Ниже приведен код, в котором дерево построения и ответ на запрос выполняются одновременно:
#include<bits/stdc++.h>
using namespace std;
const int MAX = 1000001;
struct Query
{
int l, r, idx;
};
bool cmp(Query x, Query y)
{
return x.r < y.r;
}
void update(int idx, int val, int bit[], int n)
{
for (; idx <= n; idx += idx&-idx)
bit[idx] += val;
}
int query(int idx, int bit[], int n)
{
int sum = 0;
for (; idx>0; idx-=idx&-idx)
sum += bit[idx];
return sum;
}
void answeringQueries(int arr[], int n, Query queries[], int q)
{
// initialising bit array
int bit[n+1];
memset(bit, 0, sizeof(bit));
// holds the rightmost index of any number
// as numbers of a[i] are less than or equal to 10^6
int last_visit[MAX];
memset(last_visit, -1, sizeof(last_visit));
// answer for each query
int ans[q];
int j = 0;
for (int i = 0; i < q; i++)
{
while (j <= queries[i].r)
{
if (last_visit[arr[j]] != -1)
update(last_visit[arr[j]]+1,-1,bit,n);
update(j+1,1,bit,n);
last_visit[arr[j]] = j;
j++;
}
ans[queries[i].idx] =
query(queries[i].r + 1, bit, n)-
query(queries[i].l, bit, n);
}
// print answer for each query
for (int i=0; i<q; i++)
cout << ans[i] << endl;
}
int main() {
int a[] = {1, 1, 1, 1, 1};
int n = sizeof(a)/sizeof(a[0]);
Query queries[3];
queries[0].l = 0;
queries[0].r = 0;
queries[0].idx = 0;
queries[1].l = 1;
queries[1].r = 3;
queries[1].idx = 1;
queries[2].l = 2;
queries[2].r = 4;
queries[2].idx = 2;
int q = sizeof(queries)/sizeof(queries[0]);
sort(queries, queries+q, cmp);
answeringQueries(a, n, queries, q);
return 0;
}
Мой вопрос таков: как мне узнать, должен ли я отвечать на запросы одновременно с построением дерева или должен отвечать на них один за другим после построения дерева.