Dhruv Chandhok - 1 year ago 72

C Question

I came across a problem from a recent competition.

I was unable to figure out a solution, and no editorial for the question is yet available.

Question Link

I am quoting the problem statement here also in case the link doesn't work.

Find the number of integers n which are greater than or equal to A and less than or equal to B (A<= n <=B) and the

The first line contains an integer T i.e. number of test cases. T lines follow, each containing two integers A and B.

`1 <= T <= 10^5`

A<=B

A,B <= 10^150

Print T lines each containing the answer to the corresponding testcase.

`2`

36 36

100 500

`1`

0

Answer Source

In general, you can try solving these problems by finding some pattern in the output. Our team got this problem accepted at the contest. Our approach was to find a general pattern in the values that satisfy the criteria. If you print the first few such digits, then you will find the following pattern

```
36
736
8736
48736
948736
```

Thus the next number after 948736 should be of 7 digits and can be any one of 1948736, 2948736, 3948736, 4948736, 5948736, 6948736, 7948736, 8948736, 9948736. Thus check which value is valid and you have the next number. Continuing in this fashion you can back yourself to get all the 150 numbers.

But there is a problem here. There will be some numbers that do not immediately follow from the previous number by appending '1' to '9'. To counter this you can now start appending values from 10 to 99 and now check if there is a valid number or not. If there is still no valid number, then again try appending numbers from 100 to 999.

Now employing this hack, you will get all the 137 values that satisfy the criterion given in the question and easily answer all the queries. For example, working java code that implements this is shown here. It prints all the 137 values.

```
import java.io.*;
import java.math.*;
import java.util.*;
class Solution
{
public static void main(String[] args)throws java.lang.Exception{
new Solution().run();
}
void run()throws java.lang.Exception{
BigInteger[] powers = new BigInteger[152];
powers[0] = one;
for(int i=1; i<=150; i++){
powers[i] = powers[i-1].multiply(ten);
}
BigInteger[] answers = new BigInteger[152];
answers[2] = BigInteger.valueOf(36);
answers[3] = BigInteger.valueOf(736);
int last = 3;
for(int i=4; i<=150; i++){
int dif = i-last;
BigInteger start = ten.pow(dif-1);
BigInteger end = start.multiply(ten);
while(start.compareTo(end) < 0){
BigInteger newVal = powers[last].multiply(start);
newVal = newVal.add(answers[last]);
BigInteger modPow = pow(two, newVal, powers[i]);
if(modPow.equals(newVal)){
answers[i] = newVal;
System.out.println(answers[i]);
last = i;
break;
}
start = start.add(one);
}
}
}
BigInteger pow(BigInteger b, BigInteger e, BigInteger mod){
if(e.equals(zero)){
return one;
}
if(e.mod(two).equals(zero)){
BigInteger x = pow(b, e.divide(two), mod);
x = x.multiply(x).mod(mod);
return x;
}else{
BigInteger x = pow(b, e.divide(two), mod);
x = x.multiply(x).mod(mod);
x = x.multiply(two).mod(mod);
return x;
}
}
BigInteger ten = BigInteger.valueOf(10);
BigInteger zero = BigInteger.ZERO;
BigInteger one = BigInteger.ONE;
BigInteger two = BigInteger.valueOf(2);
}
```