1

I have a vector of pairs of length N. Now i have Q queries of type given range let say L to R, find the minimum value of second element of pair whose first element is equal to given number K.

For example :

vector of 6 elements [{2,5},{8,7},{2,3},{8,6},{2,1},{8,4}]

Now for query : L=3 R=6 (1-based indexing) and K=8

Answer would be -> 4 which corresponds to this pair {8,4}

Constraints :

Q<=100000

N<=100000

value of first and second element of pair <=100000

I was thinking of segment tree approach, basically for every unique "first" element of pair let say v1, create a array , which has its elements made up of "second" element of original pair where "first" element value is v1;

Now for each v1 array ,create segment tree which store minimum element for a given range.

Then ,we can simply query corresponding "v1" segment tree for the above problem

My approach is very complex, can someone give me an idea how to approach this problem efficiently.

Community
  • 1
  • 1
tempEngineer
  • 223
  • 1
  • 3
  • 13
  • 2
    Please take some time to refresh [how to ask good questions](http://stackoverflow.com/help/how-to-ask), as well as [this question checklist](https://codeblog.jonskeet.uk/2012/11/24/stack-overflow-question-checklist/). – Some programmer dude Apr 12 '19 at 07:30
  • 2
    Please elaborate "very complex". Ideally show it as code here. The point is that you have to demonstrate your own effort at solving this and turn this into a quesiton on a specific programming problem. As it currently is, your question gives the strong impression of being just another one of those "Here are my requirements, please give the code." questions. If your code really is so complex that you cannot show it here, then please study and apply the concept of making a [mcve]. Otherwise try to convince us that you did do some own attempts in any way you like. "I tried - honest!" does not. – Yunnosch Apr 12 '19 at 07:49
  • 1
    Making {8, 1} from {8, 7} would make the meaning of L/R more obvious... – Aconcagua Apr 12 '19 at 07:49
  • How about instead of `k` segment trees, just have one segment tree, where instead of pointing to a single min value, point to a map of key -> min value? – גלעד ברקן Apr 12 '19 at 13:48
  • @גלעד-ברקן i think your approach will be similar in terms of space and time complexity, as while creating map of particular node(segment) ,we need to traverse all the keys in map of both the child nodes(segments) – tempEngineer Apr 12 '19 at 14:13
  • 1
    I don't understand. If you can use one segment tree to query a single value in a traditional Range Minimum Query, what's the difference between having an extra `O(1)` step to put in a key, `k`, and get the appropriate minimum value for the range, limiting the subset to tuples `{k, _}`? – גלעד ברקן Apr 12 '19 at 14:34
  • I agree, though you approach is cleaner but what i was saying is that in terms of space and time complexity it is somewhat similar. But anyway thanks, will try to do using you way. If there is more efficient approach in terms of space or time complexity, please let me know – tempEngineer Apr 12 '19 at 14:38

2 Answers2

1

You can also use the map in this case since the out put required by you is the second value. So treat the first value as key and the next as its value. for eg. in given range 3 to 6(1 based indexing) your map will be ass following. 2->[3,1] 8->[6,4] now the extract of the code looks like.

map<int,vector<int>> m;// my map already contains the value, i suppose you know that.
vector<int> temp;
temp=m[k];//here k=8 as given
//find the smallest element in the given array temp.
// this method give O(nlogn) complexity

sort(temp.begin(),temp.end());
cout<<temp[0];

// this method will take complexity of o(n)
int min=INT_MAX;
for(int i=0;i<temp.size();i++)
{
    if(temp[i]<min)
    {
       min=temp[i];
     }

}
cout<<min;


0

Take your inputs pairs and create an array of triples T from them, using this formula:

(ai, bi) becomes ti = (ai, i, bi)

Then sort T. Compute a segment tree on T so that you can get the min of the third field in O(log(n)) when you know the start and end index of a sub-array of T.

Define the constant:

int const nOO = std::numeric_limits<int>::min();
int const pOO = std::numeric_limits<int>::max();

When reveiving the query: (K, L, R). Use lower_bound() on T with (K, L, nOO) to find the start of the T sub-array where triples have K or greater as the first item and have index greater or equal to L.

Use upper_bound() with (K, R, pOO) to find the end of the sub-array (end excluded).

You can now use your segment tree to retrieve the min of bi knowing the two bounds in T.

Complexity should be O(3*log(n)) = O(log(n)) for each query and O(n*log(n)) for the initial construction of the T array and segment tree.

fjardon
  • 7,921
  • 22
  • 31