Given an array **arr[] **consisting of integers and queries **Q** of the form **(L, R)**, the task is to check whether any non-repeating element is present within indices **[L, R]***(1 based indexing)* or not. If there is at least one non-repeating element, then print **“Yes”**. Otherwise, print **“No”**.

**Examples:**

Input:arr[] = {1, 2, 1, 2, 3, 4}, Queries[][] = {{1, 4}, {1, 5}}

Output:No Yes

Explanation:

For the first query, the subarray is {1, 2, 1, 2}, we can see that both number have frequency 2. Therefore, the answer is No.

For the second query, the subarray is {1, 2, 1, 2, 3}, we can see that 3 has frequency 1 so the answer is Yes.

Input:arr[] = {1, 2, 3, 4, 5}, Queries[][] = {{1, 4}}

Output:Yes

Explanation:The subarray is {1, 2, 3, 4}, has all elements as frequency 1 so the answer is Yes.

**Naive Approach: **

The simplest approach to solve the problem is to iterate over a given subarray for each query and maintain a map for storing the frequency of each element. Iterate over the map and check whether there is an element of frequency 1 or not.

**Time Complexity: **O(Q * N)

**Auxiliary Space Complexity: **O(N)

**Efficient Approach: **The key observation for the solution is, for the element to have frequency 1 in the given array, the **previous occurrence** of this number in the array is strictly less than the query l and **next occurrence** of the element is strictly greater than r of some query. Use this observation to find order. Below are the steps that use the Merge Sort Tree approach to solve the given problem:

- Store the previous occurrence and next occurrence of every
**ith**element in the array as pair. - Build the merge sort tree and merge nodes in them according to the previous occurrence. The merge function is used to merge the ranges.
- At each node of merge sort tree, maintain prefix maximum on the next occurrence because we need as smallest possible previous occurrence and as big next occurrence of some element.
- For answering the query, we need node with previous occurrence strictly less than l.
- For the element in the merge sort tree with the previous occurrence less than l, find the max next occurrence and check if next occurrence is greater than r of the query, then there is an element present in the subarray with frequency 1.

Below is the implementation of the above approach:

## CPP

`// C++ program for the above approach ` `#include <bits/stdc++.h> ` `using` `namespace` `std; ` ` ` `const` `int` `INF = 1e9 + 9; ` `const` `int` `N = 1e5 + 5; ` ` ` `// Merge sort of pair type for storing ` `// prev and next occurrences of element ` `vector<vector<pair<` `int` `, ` `int` `> > > segtree(4 * N); ` ` ` `// Stores the occurrences ` `vector<pair<` `int` `, ` `int` `> > occurrences(N); ` ` ` `// Finds occurrences ` `vector<set<` `int` `> > pos(N); ` ` ` `int` `n; ` ` ` `// Function to build merge sort tree ` `void` `build(` `int` `node = 0, ` `int` `l = 0, ` ` ` `int` `r = n - 1) ` `{ ` ` ` ` ` `// For leaf node, push the prev & ` ` ` `// next occurrence of the lth node ` ` ` `if` `(l == r) { ` ` ` `segtree[node].push_back(occurrences[l]); ` ` ` `return` `; ` ` ` `} ` ` ` ` ` `int` `mid = (l + r) / 2; ` ` ` ` ` `// Left recursion call ` ` ` `build(2 * node + 1, l, mid); ` ` ` ` ` `// Right recursion call ` ` ` `build(2 * node + 2, mid + 1, r); ` ` ` ` ` `// Merging the left child and right child ` ` ` `// according to the prev occurrence ` ` ` `merge(segtree[2 * node + 1].begin(), ` ` ` `segtree[2 * node + 1].end(), ` ` ` `segtree[2 * node + 2].begin(), ` ` ` `segtree[2 * node + 2].end(), ` ` ` `back_inserter(segtree[node])); ` ` ` ` ` `// Update the next occurrence ` ` ` `// with prefix maximum ` ` ` `int` `mx = 0; ` ` ` ` ` `for` `(` `auto` `& i : segtree[node]) { ` ` ` ` ` `// Update the maximum ` ` ` `// next occurrence ` ` ` `mx = max(mx, i.second); ` ` ` ` ` `// Update the next occurrence ` ` ` `// with prefix max ` ` ` `i.second = mx; ` ` ` `} ` `} ` ` ` `// Function to check whether an ` `// element is present from x to y ` `// with frequency 1 ` `bool` `query(` `int` `x, ` `int` `y, ` `int` `node = 0, ` ` ` `int` `l = 0, ` `int` `r = n - 1) ` `{ ` ` ` `// No overlap condition ` ` ` `if` `(l > y || r < x || x > y) ` ` ` `return` `false` `; ` ` ` ` ` `// Complete overlap condition ` ` ` `if` `(x <= l && r <= y) { ` ` ` ` ` `// Find the first node with ` ` ` `// prev occurrence >= x ` ` ` `auto` `it = lower_bound(segtree[node].begin(), ` ` ` `segtree[node].end(), ` ` ` `make_pair(x, -1)); ` ` ` ` ` `// No element in this range with ` ` ` `// previous occurrence less than x ` ` ` `if` `(it == segtree[node].begin()) ` ` ` `return` `false` `; ` ` ` ` ` `else` `{ ` ` ` ` ` `it--; ` ` ` ` ` `// Check if the max next ` ` ` `// occurrence is greater ` ` ` `// than y or not ` ` ` `if` `(it->second > y) ` ` ` `return` `true` `; ` ` ` `else` ` ` `return` `false` `; ` ` ` `} ` ` ` `} ` ` ` ` ` `int` `mid = (l + r) / 2; ` ` ` `bool` `a = query(x, y, 2 * node + 1, l, mid); ` ` ` `bool` `b = query(x, y, 2 * node + 2, mid + 1, r); ` ` ` ` ` `// Return if any of the ` ` ` `// children returned true ` ` ` `return` `(a | b); ` `} ` ` ` `// Function do preprocessing that ` `// is finding the next and previous ` `// occurrences ` `void` `preprocess(` `int` `arr[]) ` `{ ` ` ` ` ` `// Store the position of ` ` ` `// every element ` ` ` `for` `(` `int` `i = 0; i < n; i++) { ` ` ` `pos[arr[i]].insert(i); ` ` ` `} ` ` ` ` ` `for` `(` `int` `i = 0; i < n; i++) { ` ` ` ` ` `// Find the previous ` ` ` `// and next occurrences ` ` ` `auto` `it = pos[arr[i]].find(i); ` ` ` `if` `(it == pos[arr[i]].begin()) ` ` ` `occurrences[i].first = -INF; ` ` ` ` ` `else` ` ` `occurrences[i].first = *prev(it); ` ` ` ` ` `// Check if there is no next occurrence ` ` ` `if` `(next(it) == pos[arr[i]].end()) ` ` ` ` ` `occurrences[i].second = INF; ` ` ` `else` ` ` `occurrences[i].second = *next(it); ` ` ` `} ` ` ` ` ` `// Building the merge sort tree ` ` ` `build(); ` `} ` ` ` `// Function to find whether there is a ` `// number in the subarray with 1 frequency ` `void` `answerQueries(` `int` `arr[], ` ` ` `vector<pair<` `int` `, ` `int` `> >& queries) ` `{ ` ` ` `preprocess(arr); ` ` ` ` ` `// Answering the queries ` ` ` `for` `(` `int` `i = 0; i < queries.size(); i++) { ` ` ` `int` `l = queries[i].first - 1; ` ` ` `int` `r = queries[i].second - 1; ` ` ` ` ` `bool` `there = query(l, r); ` ` ` ` ` `if` `(there == ` `true` `) ` ` ` `cout << ` `"Yes\n"` `; ` ` ` ` ` `else` ` ` `cout << ` `"No\n"` `; ` ` ` `} ` `} ` ` ` `// Driver Code ` `int` `main() ` `{ ` ` ` `int` `arr[] = { 1, 2, 1, 2, 3, 4 }; ` ` ` `n = ` `sizeof` `(arr) / ` `sizeof` `(arr[0]); ` ` ` ` ` `vector<pair<` `int` `, ` `int` `> > queries = { { 1, 4 }, { 1, 5 } }; ` ` ` ` ` `answerQueries(arr, queries); ` `} ` |

*chevron_right*

*filter_none*

**Output:**

No Yes

**Time Complexity:** *O(N*log(N) + Q*log ^{2}(N))*

**Auxiliary Space:**

*O(N*log(N))*

## Recommended Posts:

- Array range queries for searching an element
- Queries for the minimum element in an array excluding the given index range
- Find the element having maximum set bits in the given range for Q queries
- Range Queries to find the Element having Maximum Digit Sum
- Array range queries over range queries
- Queries to check whether a given digit is present in the given Range
- Queries to check whether all the elements in the given range occurs even number of times
- Min-Max Range Queries in Array
- Find the Initial Array from given array after range sum queries
- Range product queries in an array
- Queries for GCD of all numbers of an array except elements in a given range
- Range Queries for Frequencies of array elements
- Range Update Queries to XOR with 1 in a Binary Array.
- Queries for bitwise OR in the index range [L, R] of the given array
- Sum of prime numbers in range [L, R] from given Array for Q queries
- Queries for bitwise AND in the index range [L, R] of the given array
- Array range queries for elements with frequency same as value
- Range queries for alternatively addition and subtraction on given Array
- Queries for counts of array elements with values in given range
- Range sum queries for anticlockwise rotations of Array by K indices

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.