# Queries to check if any non-repeating element exists within range [L, R] of an Array

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 YesExplanation:

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:YesExplanation: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);` `}` |

**Output:**

No Yes

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

**Auxiliary Space:**

*O(N*log(N))*

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the **DSA Self Paced Course** at a student-friendly price and become industry ready. To complete your preparation from learning a language to DS Algo and many more, please refer **Complete Interview Preparation Course****.**

In case you wish to attend **live classes **with experts, please refer **DSA Live Classes for Working Professionals **and **Competitive Programming Live for Students**.