Question 4
You are given some ranges [l, r] and a pseudocode to check whether i exists in the range or not. The pseudocode:
while(l < r) {
int m = (l+r)/2
if(i < m) {
r = m-1;
} else if(i > m) {
l = m+1;
} else {
cout << "Found";
break;
}
}
You need to find the probability that the psudocode will fail. For example, given range [2, 9], the probability that it will fail is 1/2, since 2, 4, 6 and 9 will not be found with the code and total number of elements is 8, so probability 4/8 = 1/2. You have to answer the queries modulo 10^9+7, so the final answer for the above range would be 500000004. The input is a 2D array where each element array is of size 2 denoting the range [l, r].
1 <= l <= r <= 10^6 for each query.
The input consists of a 2d array.
Solution :
This can be solved using dynamic programming. We calculate the number of elements which give correct answer and then subtract it from the length of the segment to get the incorrect answers. Every time we have a segment, we can see that the number of elements we get from it is dependent on the subparts we divide it into. For some length 'len', we have 1 answer for the midpoint and then we divide into two parts, one of size (len/2) and the other of size (len-len/2-1), since we are not taking the middle element for the next steps. The relation to calculate the number of correct elements given the length of the segment is as follows:
R(len) = {
0 if len = 1,
1 if len = 2 or len = 3,
R(len/2)+R(len-len/2-1)+1 otherwise, (len/2 denotes floor division)
}
We add 1 to the last case because we can get 1 element from that length and R(len/2)+R(len-len/2-1) from the subparts.
So we call R(r-l+1) for every query to get the answer, and we can use a map or array to store the answers for the subproblems, so it won't time out for larger cases.