Reputation: 689
Take an unsorted array like:
4,5,1,2,3,7,8,3
and queries be like:
[1 2] [5 5] [2 6] [6 6] [1 6] [1 5]
where each query represents a interval of indices.
Length of array and total queries can be upto 100000.
I want to calculate the number of occurences of every index in each of the queries like below:
occurences of 1: 3
occurences of 3: 3
occurences of 5: 4, etc
Any optimal way to perform this ? I have tried in naive way but need some hints for optimal solution.
Upvotes: 0
Views: 72
Reputation: 9447
You can solve it by BIT(binary index tree) or Segment-Tree..
I attached two link there to learn about those algoritm...
BIT solution:
For each query lets range: [l r]
:
l to n
with value 1
.r+1 to n
...so update r+1 to n
with
value -1
in BIT..Each update operation take log(n) in BIT...
Calculate number of occurances for each index:
Call sum(index) in BIT to get count
This operation take log(n) time..
Complexity:
complexity of this solution: Q*(log(n)+log(n)) + N *(log(n))
..
Code:
#include <bits/stdc++.h>
using namespace std;
int tree[100005], A[100005];
void update(int idx, int n, int v) {
while (idx <= n) {
tree[idx] += v;
idx += (idx & -idx);
}
}
int sum(int idx) {
int res = 0;
while (idx) {
res += tree[idx];
idx -= (idx & -idx);
}
return res;
}
int main() {
int n, q, i, l, r;
scanf("%d", &n);
for (i = 1; i <= n; i++) {
scanf("%d", &A[i]);
}
scanf("%d", &q);
memset(tree, 0, sizeof(tree));
while (q--) {
scanf("%d%d", &l, &r);
update(l,n,1);
update(r+1,n,-1);
}
for (i = 1; i <= n; i++) {
printf("%d\n", sum(i));
}
return 0;
}
Upvotes: 1