In this HackerRank Inverse RMQ problem solution, we have given an array of distinct integers with size n = 2k and m queries. we need to find the minimum element on subsegment [Li, Ri].

## Problem solution in Python.

```import sys
import heapq

n = int(input())
a = list(map(int, input().split()))
freq = dict()
for i in a:
if i not in freq:
freq[i] = 0
freq[i] += 1
if len(freq) < n:
print("NO")
sys.exit()
exp_freq = 1
depth = 1
while 2**(depth - 1) < n:
depth += 1
prev = dict()
ans = [0] * (n + n - 1)
while exp_freq <= n:
v = list()
v1 = list()
for key in prev:
v1.append((key, prev[key]))
for key in freq:
if freq[key] == depth:
v.append(key)
if len(prev) == 0:
ans[0] = v[0]
prev[v[0]] = 0
freq[v[0]] -= 1
exp_freq *= 2
depth -= 1
continue
v.sort()
v1.sort()
cur = exp_freq // 2 - 1
pq = list()
j = 0
for i in v:
if i in prev:
ans[prev[i] * 2 + 1] = i
prev[i] = prev[i] * 2 + 1
freq[i] -= 1
else:
while j < len(v1):
if v1[j][0] < i:
heapq.heappush(pq, v1[j][1])
j += 1
else:
break
if len(pq) == 0:
print("NO")
sys.exit()
temp = heapq.heappop(pq)
ans[temp * 2 + 2] = i
prev[i] = temp * 2 + 2
freq[i] -= 1
exp_freq *= 2
depth -= 1
print("YES")
for i in ans:
print(i, end=" ")
```

{"mode":"full","isActive":false}

## Problem solution in Java.

```import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.HashMap;
import java.io.IOException;
import java.util.TreeSet;
import java.util.TreeMap;
import java.util.StringTokenizer;
import java.util.Map;
import java.util.Map.Entry;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.io.InputStream;

/**
* Built using CHelper plug-in
* Actual solution is at the top
*/
public class Solution {
public static void main(String[] args) {
InputStream inputStream = System.in;
OutputStream outputStream = System.out;
OutputWriter out = new OutputWriter(outputStream);
InversedRMQ solver = new InversedRMQ();
solver.solve(1, in, out);
out.close();
}

static class InversedRMQ {
public void solve(int testNumber, InputReader in, OutputWriter out) {
int k = 2 * n - 1;
final Map<Integer, Integer> count = new TreeMap<>();
for (int i = 0; i < k; i++) {
count.put(x, count.getOrDefault(x, 0) + 1);
}
final TreeSet<Integer>[] types = new TreeSet[k + 1];
final Map<Integer, Integer> result = new HashMap<>();
for (int i = 0; i < types.length; i++) {
types[i] = new TreeSet<>();
}
int log = 0, n_ = n;
while (n_ > 0) {
n_ >>= 1;
log++;
}
for (Map.Entry<Integer, Integer> entry : count.entrySet()) {
if (types[entry.getValue()].isEmpty()) {
out.printLine("NO");
return;
}
int wh = types[entry.getValue()].pollFirst();
result.put(entry.getKey(), wh);
for (int i = 0; i < entry.getValue() - 1; i++) {
types[entry.getValue() - i - 1].add(wh * 2 + 1);
wh <<= 1;
}
}
final int[] ans = new int[k + 1];
for (Map.Entry<Integer, Integer> entry : result.entrySet()) {
int wh = entry.getValue(), value = entry.getKey();
while (wh <= k) {
ans[wh] = value;
wh <<= 1;
}
}
out.printLine("YES");
for (int i = 1; i <= k; i++) {
out.print(ans[i], ' ');
}
out.printLine();
}

}

static class OutputWriter {
private PrintWriter writer;

public OutputWriter(Writer writer) {
this.writer = new PrintWriter(writer);
}

public OutputWriter(OutputStream stream) {
this(new OutputStreamWriter(stream));
}

public void print(Object... args) {
for (Object arg : args) {
writer.print(arg);
}
}

public void printLine(Object... args) {
print(args);
writer.println();
}

void close() {
writer.close();
}

}

private StringTokenizer tokenizer;

}

}

public String nextLine() {
try {
} catch (IOException e) {
throw new RuntimeException(e);
}
}

while (tokenizer == null || !tokenizer.hasMoreTokens()) {
tokenizer = new StringTokenizer(nextLine());
}
}

}

}
}
```

{"mode":"full","isActive":false}

## Problem solution in C++.

```#include<bits/stdc++.h>
using namespace std;
void Q(){
cout << "NO" << endl;
exit(0);
}
int Ar[(1 << 20)] , X , nn;
vector<int> Ans[(1 << 20)];
void build(int lvl , int V , bool F){
if(lvl == nn)return ;
set<int> :: iterator no = Adj[lvl].upper_bound(V);
if(F && (no == Adj[lvl].end() || *no <= V)){
Q();
}
if(F){
int x = *no;
Ans[lvl].push_back(x);
build(lvl + 1 , x , 0);
build(lvl + 1 , x , 1);
}
else {
Ans[lvl].push_back(V);
build(lvl + 1 , V , 0);
build(lvl + 1 , V , 1);
}
}
int main()
{
int n;
cin >> n;
vector<int> A(2 * n - 1);
map<int , int > mp ;
map<int , set<int> > mp1;
if(n == 1){
cin >> n;
cout << "YES\n" << n << endl;;
return 0;
}
int N = 2 * n - 1 , mx = 0 , idx = 0;
for(int i = 0 ;i < N ; i ++){
cin >> A[i] , mp[A[i]] ++;
if(mp[A[i]] > mx)
mx = mp[A[i]] , idx = A[i];
}
//if(mp.begin() -> first != idx)  Q();
set<int> S;
for(int i = 0 ;i < N ;i ++)
mp1[mp[A[i]]].insert(A[i]),  S.insert(A[i]);
for(int m = n / 2 , x = 1; m ; m >>= 1 , x ++){
if(mp1[x].size() != m)
Q();
}
for(auto no : S)
nn = mx + 1 ;
build(1 , KK , 0);
cout << "YES\n";
for(int i = 1; i <= mx ;i ++)
for(int l = 0; l < Ans[i].size() ;l ++)
cout << Ans[i][l] << " ";

}
```

{"mode":"full","isActive":false}

## Problem solution in C.

```#include <assert.h>
#include <stddef.h>
#include <limits.h>
#include <math.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char** split_string(char*);

int* canTree(int n, int* arr){
int logn = 0;
while(n >> logn > 1){
logn++;
}

int sortarr[2*n - 1];
for(int i = 0; i < 2*n - 1; i++){
sortarr[i] = arr[i];
int curr = i;
int inplace = 0;
while(curr > 0 && inplace == 0){
int next = (curr - 1)/2;
if(sortarr[next] < sortarr[curr]){
int temp = sortarr[curr];
sortarr[curr] = sortarr[next];
sortarr[next] = temp;
curr = next;
}
else{
inplace = 1;
}
}
}

for(int i = 0; i < 2*n - 1; i++){
int temp = sortarr[0];
sortarr[0] = sortarr[2*n - i - 2];
sortarr[2*n - i - 2] = temp;

int curr = 0;
int reheaped = 0;
while(reheaped == 0){
int next = curr;
if(2*curr + 1 < 2*n - i - 2 && sortarr[2*curr + 1] > sortarr[next]){
next = 2*curr + 1;
}
if(2*curr + 2 < 2*n - i - 2 && sortarr[2*curr + 2] > sortarr[next]){
next = 2*curr + 2;
}
if(next != curr){
temp = sortarr[curr];
sortarr[curr] = sortarr[next];
sortarr[next] = temp;
curr = next;
}
else{
reheaped = 1;
}
}
}

int *levellist[logn + 1];
int numatlevel[logn + 1];
int **numopen[logn + 1];
for(int i = 0; i <= logn; i++){
levellist[i] = malloc((1<<i)*sizeof(int));
assert(levellist[i] != NULL);
for(int j = 0; j < 1<<i; j++){
levellist[i][j] = INT_MIN;
}
numopen[i] = malloc((1<<i)*sizeof(int*));
assert(numopen[i] != NULL);
for(int j = 0; j <= (1<<i); j++){
numopen[i][j] = malloc((logn + 1)*sizeof(int));
assert(numopen[i][j] != NULL);
for(int k = 0; k <= logn; k++){
numopen[i][j][k] = 0;
}
}
numatlevel[i] = 0;
}
numopen[0][0][0] = 1;

int index = 0;
while(index < 2*n - 1){
int currval = sortarr[index];
int currindex = index;
while(index < 2*n - 1 && sortarr[index] == currval){
index++;
}
int numreps = index - currindex;
int level = (logn + 1) - numreps;
int pos = 0;
if(level < 0 || numopen[0][0][level] == 0){
return NULL;
}
for(int i = 0; i < level; i++){
assert(numopen[i][pos][level] > 0);
numopen[i][pos][level] -= 1;
for(int j = level + 1; j <= logn; j++){
numopen[i][pos][j] += 1;
}
if(i + 1 < level && numopen[i + 1][2*pos][level] > 0){
pos = 2*pos;
}
else{
pos = 2*pos + 1;
}
}
for(int i = level; i <= logn; i++){
levellist[i][pos] = currval;
for(int j = i + 1; j <= logn; j++){
numopen[i][pos][j] += 1;
}
pos = 2*pos;
}
}

int *toreturn = malloc((2*n - 1)*sizeof(int));
assert(toreturn != NULL);
index = 0;
for(int i = 0; i <= logn; i++){
for(int j = 0; j < (1<<i); j++){
toreturn[index] = levellist[i][j];
index++;
}
}

}

int main() {
FILE* fptr = fopen(getenv("OUTPUT_PATH"), "w");

char* n_endptr;
int n = strtol(n_str, &n_endptr, 10);

if(n_endptr == n_str || *n_endptr != '\0'){ exit(EXIT_FAILURE);}

int *treelist = malloc((2*n - 1) * sizeof(int));

for(int i = 0; i < 2*n - 1; i++){
char* currval_str = vals_str[i];
char* currval_endptr;
int currval = strtol(currval_str, &currval_endptr, 10);

if(currval_endptr == currval_str || *currval_endptr != '\0'){ exit(EXIT_FAILURE);}
treelist[i] = currval;
}
int* arrlist = canTree(n, treelist);
if(arrlist == NULL){
fprintf(fptr, "NO");
}
else{
fprintf(fptr, "YES\n");
for(int i = 0; i < 2*n - 2; i++){
fprintf(fptr, "%d ", arrlist[i]);
}
fprintf(fptr, "%d", arrlist[2*n - 2]);
}
return 0;
}

size_t alloc_length = 1024;
size_t data_length = 0;
char* data = malloc(alloc_length);

while (true) {
char* cursor = data + data_length;
char* line = fgets(cursor, alloc_length - data_length, stdin);

if (!line) { break; }

data_length += strlen(cursor);

if (data_length < alloc_length - 1 || data[data_length - 1] == '\n') { break; }

size_t new_length = alloc_length << 1;
data = realloc(data, new_length);

if (!data) { break; }

alloc_length = new_length;
}

if (data[data_length - 1] == '\n') {
data[data_length - 1] = '\0';
}
if(data[data_length - 1] != '\0'){
data_length++;
data = realloc(data, data_length);
data[data_length - 1] = '\0';
}

data = realloc(data, data_length);

return data;
}

char** split_string(char* str) {
char** splits = NULL;
char* token = strtok(str, " ");

int spaces = 0;

while (token) {
splits = realloc(splits, sizeof(char*) * ++spaces);
if (!splits) {
return splits;
}

splits[spaces - 1] = token;

token = strtok(NULL, " ");
}

return splits;
}
```

{"mode":"full","isActive":false}