Algorithm


Problem link- https://www.spoj.com/problems/DQUERY/

DQUERY - D-query

 

 

 

Given a sequence of n numbers a1, a2, ..., an and a number of d-queries. A d-query is a pair (i, j) (1 ≤ i ≤ j ≤ n). For each d-query (i, j), you have to return the number of distinct elements in the subsequence ai, ai+1, ..., aj.

Input

  • Line 1: n (1 ≤ n ≤ 30000).
  • Line 2: n numbers a1, a2, ..., an (1 ≤ ai ≤ 106).
  • Line 3: q (1 ≤ q ≤ 200000), the number of d-queries.
  • In the next q lines, each line contains 2 numbers i, j representing a d-query (1 ≤ i ≤ j ≤ n).

Output

  • For each d-query (i, j), print the number of distinct elements in the subsequence ai, ai+1, ..., aj in a single line.

     

Example

Input
5
1 1 2 1 3
3
1 5
2 4
3 5

Output
3
2
3 

 

Code Examples

#1 Code Example with C++ Programming

Code - C++ Programming

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
 
#define MOD                 1000000007LL
#define EPS                 1e-9
#define io                  ios_base::sync_with_stdio(false);cin.tie(NULL);
#define M_PI                3.14159265358979323846

template <typename T> T gcd(T a, T b){return (b==0)?a:gcd(b,a%b);}
template <typename T> T lcm(T a, T b){return a*(b/gcd(a,b));}
template <typename T> T mod_exp(T b, T p, T m){T x = 1;while(p){if(p&1)x=(x*b)%m;b=(b*b)%m;p=p>>1;}return x;}
template <typename T> T invFermat(T a, T p){return mod_exp(a, p-2, p);}
template <typename T> T exp(T b, T p){T x = 1;while(p){if(p&1)x=(x*b);b=(b*b);p=p>>1;}return x;}

const int N = 3e4+5;
const int M = 2e5+5;
const int SQN = sqrt(N) + 1;

int n, q;

struct query{
	int l, r;
	int idx;
	int block;
	query(){}
	query(int _l, int _r, int _id){
		l = _l;
		r = _r;
		idx = _id;
		block = l/SQN;
	}
	bool operator < (const query &b) const{
		if(block != b.block){
			return block < b.block;
		}
		return r < b.r;
	}
};

int arr[N];
query Q[M];
int print[M];
int cnt[1000005];

int main(){
	scanf("%d", &n);
	for(int i = 1;i <= n; i++){
		scanf("%d", arr+i);
	}
	cin >> q;
	for(int i = 1;i <= q; i++){
		int l, r;
		scanf("%d%d", &l, &r);
		Q[i] = query(l, r, i);
	}
	sort(Q+1, Q+1+q);
	int curl = 1, curr = 0;
	ll ans = 0;
	for(int i = 1;i <= q; i++){
		int l = Q[i].l;
		int r = Q[i].r;
		int id = Q[i].idx;
		while(curr < r){
			++curr;
			cnt[arr[curr]]++;
			if(cnt[arr[curr]] == 1>
				ans++;
		}
		while(curl > l){
			--curl;
			cnt[arr[curl]]++;
			if(cnt[arr[curl]] == 1)
				ans++;
		}
		while(curr > r){
			cnt[arr[curr]]--;
			if(cnt[arr[curr]] == 0)
				ans--;
			--curr;
		}
		while(curl < l){
			cnt[arr[curl]]--;
			if(cnt[arr[curl]] == 0)
				ans--;
			++curl;
		}
		print[id] = ans;
	}
	for(int i = 1; i <= q; i++)
		printf("%d\n", print[i]);
	return 0;
}
Copy The Code & Try With Live Editor

Input

x
+
cmd
5
1 1 2 1 3
3
1 5
2 4
3 5

Output

x
+
cmd
3
2
3

#2 Code Example with Java Programming

Code - Java Programming

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;

/**
 * Created by sreps on 7/31/2016.
 */
public class DQUERY {

    static Integer input[];
    static Integer answer;
    static HashMap < Integer, Integer> count;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        Integer N = Integer.parseInt(br.readLine());

        String temp[] = br.readLine().split(" ");
        input = new Integer[N + 1];
        answer = 0;
        count = new HashMap < >();

        for (int i = 1; i <= N; i++) {
            input[i] = Integer.parseInt(temp[i - 1]);
        }


        Integer Q = Integer.parseInt(br.readLine());
        ArrayList<Query> queries = new ArrayList<>();
        for (int i = 0; i < Q; i++) {
            temp = br.readLine().split(" ");
            Integer left = Integer.parseInt(temp[0]);
            Integer right = Integer.parseInt(temp[1]);
            queries.add(new Query(left, right));
        }

        int currentLeft = 1, currentRight = 1;
        for (Query query : queries) {
            int left = query.left;
            int right = query.right;

            while (left < currentLeft) {
                currentLeft--;
                addition(currentLeft);
            }
            while (left > currentLeft) {
                removal(left);
                left--;
            }
            while (right < currentRight) {
                addition(right);
                right++;
            }
            while (right > currentRight) {
                removal(right);
                right--;
            }

            System.out.println(answer);
            currentLeft = query.left;
            currentRight = query.right;
        }
    }

    static class Query {
        public Integer left;
        public Integer right;

        Query(Integer left, Integer right) {
            this.left = left;
            this.right = right;
        }
    }

    public static void addition(int position) {
        Integer current = count.get(input[position]);
        if (current == null) {
            count.put(input[position], 1);
            answer++;
            return;
        }
        if (current == 0) {
            answer++;
            current = 0;
        }
        count.put(input[position], current + 1);
    }

    public static void removal(int position) {
        Integer current = count.get(input[position]);
        if (current == null) {
            return;
        }
        if (current == 1) {
            answer--;
        }
        count.put(input[position], current - 1);
    }
}
Copy The Code & Try With Live Editor

Input

x
+
cmd
5
1 1 2 1 3
3
1 5
2 4
3 5

Output

x
+
cmd
3
2
3
Advertisements

Demonstration


SPOJ Solution-D-query-Solution in C, C++, Java, Python

Previous
SPOJ Solution - Test Life, the Universe, and Everything - Solution in C, C++, Java, Python