Tuesday, 13 December 2016

Monk and Fredo number of + ve x ,y sush that a*x+b*y=d

Monk and Fredo
Fredo and you are talking about a movie that you have recently watched while Monk is busy teaching Number Theory. Sadly, Monk caught Fredo talking to you and asked him to answer his question in order to save himself from punishment. The question says:
Given two weights of a and b units, in how many different ways you can achieve a weight of d units using only the given weights? Any of the given weights can be used any number of times (including 0 number of times).
Since Fredo is not able to answer the question, he asked you to help him otherwise he will get punished.
Note: Two ways are considered different if either the number of times a is used or number of times b is used is different in the two ways.
Input Format:
The first line of input consists of an integer T denoting the number of test cases.
Each test case consists of only one line containing three space separated integers ab and d.
Output Format:
For each test case, print the answer in a separate line.
Constraints:
1T105
1a<b109
0d109
SAMPLE INPUT
 
4
2 3 7
4 10 6
6 14 0
2 3 6
SAMPLE OUTPUT
 
1
0
1
2
Explanation
Test case 1:
7 can only be achived by using 2 two times and 3 one time.
Test case 2:
6 can't be achieved by using 4 and 10. So, 0 ways are there.
Test case 3:
0 can be achieved by using 0 times 6 and 0 times 14. So, there is only one way,
Test case 4:
6 can be achieved by using 2 three times or 3 two times. So, there are two different ways of getting 6.

Brief Description: Given ab and d, find the number of pairs (x,y) such that 0x,y and ax+by=d.
Prerequisite: Euclid Extended Algorithm
Difficulty: Medium
Detailed Explanation:
As we know that ax+by=d is a linear Diophantine equation in two variables. The solution of this equation exists if and only if d is divisible by the GCD(a,b).
Solution 1:
The simplest solution is to try all the values of x and y. As we know that the values of x will be in range from [0,da]. Similarly the values of y will be in the range [0,db]. Time complexity of this solution is O(d2ab) which won't run within the time limit.
Solution 2:
ax+by=d
ax=dby
We know that for one value of y there is at-most one x which will satisfy this equation. So, iterate over all values of y in the range [0,db] and check if (dby) is divisible by a or not. Time complexity of this solution is O(db) which is better than previous solution's complexity but still not good enough to pass within the time limit.
Note: We can also iterate over all values of x from [0,da] and check if (dax) is divisible by b or not. But a<b, so db<da.
Solution 3:
Let y1 be the smallest non negative number such that (dby1) is divisible by a. We can say that y1 is the first value of y such that (dby) is divisible by a.
If we have y1, the next value of y will be y1+a.
Why ??
Let y=y1+a.
dby=db(y1+a)=dby1ba
But we know that dby1 is divisible by a and ba is also divisible by a, so db(y1+a) will also be divisible by a.
So, the values of y will be y1,y1+a,y1+2a,y1+3a,...,y1+na where y1+nadb.
The values of y seems to be a Arithmetic Progression. So we can easily calculate number of terms in the Arithmetic progression using y1+nadb equation.
n=dby1a
So number of terms in the Arithmetic progression is equal to n+1.
Now the only part thats left is to find the value of y1. An obvious solution is to iterate over all values of y and break as soon as we find the first value such that dby is divisible by a. Time complexity of this solution is O(db) in worst case. But this solution is faster then previous solutions in other cases.
Exercise: What is the worst case for this solution ?
Solution 4:
Note: A small optimization is divide both the side of the equation ax+by=d by the GCD(a,b). Why ?? Think about it.
We can compute the first value of y1 using Modulo Inverse (Extended Euclid).
ax+by=d
y=daxb
Taking modulo a both side.
y1=y%a=daxb%a=db%a
Now we need to check if (dby1) is divisible by a.
Let z=(dby1)
z%a=(dby1)%a
z%a=(d%a(b%a)(db%a))
z%a=0
So y1 is the first value of y such that (dby) is divisible by a.
We can compute y1 in O(log(max(a,b)) and number of term using the formula computed in the previous solution (n=dby1a ) in O(1).
So the overall time complexity is O(log(max(a,b))).
Time ComplexityO(log(max(a,b)))
Space ComplexityO(1
  1. #include<bits/stdc++.h>
  2. #define dd double
  3. #define ll long long
  4. using namespace std;
  5. ll g, x, y;
  6. void extendedEuclid(ll A,ll B) {
  7. if(B == 0) {
  8. g = A;
  9. x = 1;
  10. y = 0;
  11. }
  12. else {
  13. extendedEuclid(B, A%B);
  14. ll temp = x;
  15. x = y;
  16. y = temp - (A/B)*y;
  17. }
  18. }
  19. int main()
  20. {
  21. int q;
  22. cin>>q;
  23. while(q--)
  24. {
  25. ll a,b,d,e=0;
  26. cin>>a>>b>>d;
  27. extendedEuclid(a,b);
  28. if(d%g !=0){cout<<"0\n";continue;}
  29. ll k1=ceil(dd(-x)*(dd(d)/dd(b))),k2=floor((dd)y*((dd)d/(dd)a));
  30. if(k1<=k2)
  31. cout<<k2-k1+1<<"\n";
  32. else
  33. cout<<"0\n";
  34. }
  35. return 0;
  36. }

1 comment:

  1. everything is pretty clear , just one thing is bugging me .

    why you put y1 = y%a in the first place before checking that it will make the solution for the equation .
    apart from hit and trial what was the logic behind .

    ReplyDelete