1

Given an array (not sorted) and few range queries. For each query I need to find the number of unique digits within the given range. Here is the naive approach I came up with.

#include<cstdio>
#include<iostream>
using namespace std;

int main()
{
    int n; scanf("%d",&n); //Size of the array
    int a[n+1]; a[0]=0;

    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);

    int q; scanf("%d",&q); //Number of queries

    while(q--)
    {
        int x,y; scanf("%d %d",&x,&y); //Range of each query
        int bit[n+1];
        for(int i=0;i<=n;i++)
            bit[i]=0;

        for(int i=1;i<=n;i++)
        {
            for(int j=i-1;j>0;j--)
            {
                bit[i]=a[i];
                if(bit[j]==a[i])
                {
                    bit[j]=0;
                    break;
                }
            }
        }
        int cnt=0;
        for(int i=x;i<=y;i++)
        {
            if(bit[i])
                cnt++;
        }
        printf("%d\n",cnt);
    }
    return 0;

}

What is the most efficient way to do this operation? I think this can be done using Binary Indexed tree but couldn't come up with the solution.

Wasim Thabraze
  • 780
  • 1
  • 12
  • 29

1 Answers1

0

If the number of range queries is small compared to the size of the array, say O(k) vs O(n) where k << n, then:

  1. Put all range endpoints in a balanced binary tree O(klogk)
  2. Make one pass over the array and count unique elements in each subrange. Use a hash table to remember which elements we have already seen. O(n)
  3. Do an in-order traversal between range endpoints for each range query and sum subrange totals. O(k^2) worst case / O(klogk) for reasonable queries.
Imran
  • 12,950
  • 8
  • 64
  • 79