我最近开始学习Fenwick树,用于回答范围查询问题。但是我对两种查询处理感到困惑:
首先,我对输入进行预处理并为其构建一棵Fenwick树,然后逐个计算每个查询的答案。
构建和应答查询是同时进行的。我会在构建我的Fenwick树的同时回答问题。
然后我发现一个问题,它问:给定数组在[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;
}
我的问题是,我怎么知道我应该在构建树的同时回答查询还是在构建树后一个接一个地回答它们。