Count the number of triplets a*b=c - algorithm

The problem is to count the number of triplets such that
a * b = c
where a1 <= a <= a2 and b1 <= b <= b2 and c1 <= c <= c2
Input will be a1,a2,b1,b2,c1,c2
The solution that I can think is to use two nested loop that iterates from a1 to a2 and second one from b1 to b2 and multiply each of them and see if the multiplied value lies in the range c1 to c2 then increment the count.
How to efficiently solve the problem when constraints are very high i.e all a1,a2,b1,b2,c1,c2 can have value between 0 to 1000000000.

Part 1: Solution with O(a2 - a1) complexity.
First, notice that given a certain a, we can easily count the number of b values with b1 <= b <= b2, which also satisfy c1 <= a * b <= c2. The latter condition is equivalent to c1 / a <= b <= c2 / a, thus we need to count the number of integers b which satisfy max(b1, c1/a) <= b <= min(b2, c2/a).
This number is N(a) = floor(min(b2, c2/a)) - ceil(max(b1, c1/a)) + 1 -- relation (1).
The solution to the problem is N(a1) + N(a1 + 1) + ... + N(a2).
This is more efficient than looping over all (a, b) pairs and checking their product, however, it may still not be fast enough for the given magnitude of the inputs -- the complexity is O(a2 - a1). Since the problem is symmetrical in a and b, it might be more advantageous to use the O(b2 - b1) complexity.
In the following two parts I will describe a more efficient solution.
Part 2: Reducing the problem to simpler ones.
Let us denote as N(a1, a2, b1, b2, c1, c2) the value that we need to calculate.
Notice that we can reduce the problem into two problems with c1 = 0, using:
N(a1, a2, b1, b2, c1, c2) = N(a1, a2, b1, b2, 0, c2) - N(a1, a2, b1, b2, 0, c1 - 1).
We can take this further and reduce a problem where c1 = 0 into two problems where b1 = 0 and c1 = 0. This can be done using:
N(a1, a2, b1, b2, 0, C) = N(a1, a2, 0, b2, 0, C) - N(a1, a2, 0, b1 - 1, 0, C).
Similarly, we can reduce a problem where b1 = 0 and c1 = 0 into two problems with a1 = 0, b1 = 0, c1 = 0.
Therefore, it is enough to solve simpler problems which require to compute values of the following form: N(0, A, 0, B, 0, C), i.e. we need to count the number of triplets of natural numbers (a, b, c), with c = a * b, a <= A, b <= B, c <= C.
Part 3: Solution with O(sqrt(c2)) complexity.
One next useful observation is that since a * b = c <= C, at least one of the following relations is true: a <= sqrt(C), or b <= sqrt(C) -- observation (2).
In the first part of the proof (relation 1) it was shown that we can efficiently calculate (in O(1)) the number of good b values if a is fixed. Using that relation, we can efficiently count the number of triples with a <= sqrt(C) -- in O(sqrt(C)).
What remains to do is to calculate the number of triplets with a > sqrt(C). According to observation (2), we know that in this case it is required to have b <= sqrt(C).
Thus, for any b in {0, 1, 2, ..., sqrt(C)} we have to count the number of good a values such that sqrt(C) < a < A. We can once again apply relation (1) (with reversed roles for a and b this time -- we are now given b and calculate the number of good a values, which is subject to the constraint of belonging to a certain interval). For each b in {0, 1, 2, ..., sqrt(C)}, we can count the number of good a in O(1) -- therefore the complexity for this case is again O(sqrt(C)).
Using the above results, we get an overall complexity of O(sqrt(C)). Returning to the initial problem, this involves an O(sqrt(c2)) complexity.

Use the fac that ab = ba. I.e. if you have tried a=2, b=3, there is no sense in also trying a=3, b=2.
Also, once a*b > c2, there is no sense in increasing a or b.

Related

confusing question of maximum possible weight of a subsequence

The weight of a sequence a0, a1, …, an-1 of real numbers is defined as
a0+a1/2+…+ aa-1/2n-1. A subsequence of a sequence is obtained by
deleting some elements from the sequence, keeping the order of the
remaining elements the same. Let X denote the maximum possible weight
of a subsequence of a0, a1, …,an-1 and Y the maximum possible weight
of a subsequence of a1, a2, …,an-1. Then X is equal to (A) max(Y,
a0+Y) (B) max(Y, a0+Y/2) (C) max(Y, a0+2Y) (D) a0+Y/2
Answer: (B)
Explanation: Using concepts of Dynamic Programming, to find the
maximum possible weight of a subsequence of X, we will have two
alternatives:
Do not include a0 in the subsequence: then the maximum possible weight will be equal to maximum possible weight of a subsequence of
{a1, a2,….an} which is represented by Y
Include a0: then maximum possible weight will be equal to a0 + (each number picked in Y will get divided by 2) a0 + Y/2. Here you can
note that Y will itself pick optimal subsequence to maximize the
weight.
Final answer will be Max(Case1, Case2) i.e. Max(Y, a0 + Y/2). Hence
B).
Why is the 2nd alternative Y/2 using Dynamic programming?
As per my understanding, the alternatives are:
without a0,
= the maximum possible weight of a subsequence of a1, a2, …,an-1 = Y
with a0,
= a0 + the maximum possible weight of a subsequence of a1, a2, …,an-1 = a0 + Y (but in above explaination it takes Y/2. Why?)
According to the question:
the weight of the subsequence a0, a1, a2,..., an-1
is:
X = a0 + a1/2 + a2/4 .... + an-1/2^(n-1)
and, the weight of the subsequence (with a0 not included) a1, a2, a3,..., an-1
is:
Y = a1 + a2/2 .... + an-1/2^(n-2)
Now, to get X from Ywe can observe that:
X = a0 + a1/2 + a2/4 .... + an-1/2^(n-1)
=> X = a0 + (a1/2 + a2/4 .... + an-1/2^(n-1))
=> X = a0 + 1/2(a1 + a2/2 .... + an-1/2^(n-2))
=> X = a0 + 1/2(Y)
Now, applying Dynamic Programming, the max weight of the subsequence a0, a1, a2,..., an-1 will be max(Y, X) = max(Y, a0 + Y/2)
Hence option B is correct.
Without a0, the subsequence sum is
Y = a1 + a2/2 + a3/4 ....
With a0 included, the sum becomes
a0 + a1/2 + a2/4 + a3/8 ... = a0 + [1/2 * (a1 + a2/2 + a3/4 ...)] = a0 + Y/2
So the correct answer would be option B.

is there a way to compare an Array A with another array B where B is xA + y under O(n^2)?

given an array A of size n and another array called B.
B is made of array A and 2 constants x and y where Bi = x * Ai + c (i => 0,1,2, … N-1)
For example,
if A : {3, 1, 5, 7} and x = 1 and y =2, then B : {5, 3, 7 ,9}
question: find out how many times A (j+1), (j+2), …. (n -1) > Bj for j E {0, 1, … n-1 }
Using the sample input above
A: {3,1,5,7}
B: {5,3,7,9}
the answer would be 3 since
when j = 0, A3 > B0 (7>5)
when j = 1, A2 > B1 (5>3) and A3 > B1 (7>3)
since there are only 3 possibilities of A j+1 …. n -1 > Bj for j E {0, 1, … n-1 }, the output will be 3
is there a way to solve this with an algorithm below O(n^2)? thanks!
Why not insert elements of B into an order statistic tree as we iterate on A, and look up for each element we see in A, how many in the tree are lower? At each A_i, make sure all but only elements up to B_(i-1) are in the tree before the lookup. This wouldn't distinguish which Bs have higher A elements, but it seems like the question is only asking for the total number. O(n log n) time, O(n) extra space.

Find matrix with minimum number of nonzero elements to satisfy row and column sums

The problem is to find a matrix that has given row and column sums and has a minimum number of nonzero elements. Given two arrays of positive integers A[1...N] and B[1...M], sum(A)=sum(B). The arrays A and B are row and column sums respectively of an unknown NxM matrix. The elements of the matrix are non-negative integers.
Is this possible in polynomial time?
Equivalent formulation - create a minimum size multi-set C that can be created from A and from B by "breaking up numbers in smaller pieces". The multi-set C is the same as nonzero elements from the matrix. The obvious lower and upper bounds on the size of C are:
max(|A|, |B|) <= |C| <= N+M-1
As you mentioned earlier |C| <= N + M - 1
But, say you can split A and B into A1, A2 and B1, B2 such that sum(A1) = sum(B1) and sum(A2) = sum(B2), the constraint becomes smaller
|C| <= (|A1| + |B1| -1) + (|A2| + |B2| -1)
<= N + M - 2
So the goal of the problem is to split A and B into the maximum number of components A1, A2, ... Ak and B1, B2, ... Bk such that sum(Ai) = sum(Bi). In which case:
|C| <= N + M -1 -k
I don't think there is a polynomial solution to this. But the following heuristics might work.
Step 1: Sort A and B
Step 2: Find common elements between A and B and move them out into their own components
Step 3: Find sets of two elements in A that sum to an element in B and move them out. Do the same thing for two elements in B that sum to an element in A
Step 4: ....
As you can see, it becomes harder and harder as the size of the component keeps going up. But I am not sure if there is a better solution.

what does C1 mean in cryptarithmetic puzzle in polog?

Here is a snippet of cryptarithmetic in prolog
sum1( [D1|N1], [D2|N2], [D|N], C1, C, Digs1, Digs) :-
sum1( N1, N2, N, C1, C2, Digs1, Digs2),
digitsum( D1, D2, C2, D, C, Digs2, Digs).
As below explains
sum1( N1, N2, N, C1, C, Digits1, Digits)
where N1, N2 and N are our three numbers,
C1 is carry from the right, and
C is carry to the left (after the summation).
Digits1 is the list of available digits for instantiating the
variables in N1, N2, and N.
Digits is the list of digits that were not used in the
instantiation of these variables.
I really don't get it what does C1 mean in sum1( [D1|N1], [D2|N2], [D|N], C1, C, Digs1, Digs), for C2 stands for carry form right, C stands for carry to the left, then what does C1 stand for?
C,C1,C2 can only assume 0,1 values. Arithmetic rules require that C1 will be 0 in first call, and C will be 0 on last call. C2 become C on recursive call, then it propagates the carry after the sum. C1 it's the carry added to N1,N2 to get N.

Existence of a permutation under constraints (Interview Street - Manipulative Numbers)

I am trying to solve this problem: https://www.interviewstreet.com/challenges/dashboard/#problem/4f9a33ec1b8ea
Suppose that A is a list of n numbers ( A1, A2, A3, ... , An) and B ( B1, B2, B3, .. ,Bn ) is a permutation of these numbers. We say B is K-Manipulative if and only if its following value:
M(B) = min( B1 Xor B2, B2 Xor B3, B3 Xor B4, ... , Bn-1 Xor Bn, Bn Xor B1 ) is not less than 2^K.
You are given n number A1 to An, You have to find the biggest K such that there exists a permutation B of these numbers which is K-Manipulative.
Input:
In the first line of the input there is an integer N.
In the second line of input there are N integers A1 to An
N is not more than 100.
Ai is non-negative and will fit in 32-bit integer.
Output:
Print an integer to the output being the answer to the test. If there is no such K print -1 to the output.
Sample Input
3
13 3 10
Sample Output
2
Sample Input
4
1 2 3 4
Sample Output
1
Explanation
First Sample test
Here the list A is {13, 3, 10}. One possible permutation of A is, B = (10, 3, 13).
For B, min( B1 xor B2, B2 xor B3, B3 xor B1 ) = min( 10 xor 3, 3 xor 13, 13 xor 10 ) = min( 9, 14, 7 ) = 7.
So there exist a permutation B of A such that M(B) is not less than 4 i.e 2^2. However there does not exist any permutation B of A such that M(B) is not less than 8 ie 2^3. So the maximum possible value of K is 2.
==================================================================================
Here are the attempts I have made so far.
Attempt 1: Greedy Algorithm
Place the input in an array A[1..n]
Compute the value M(A). This gives the location of the min XOR value (i, (i + 1) % n)
Check whether swapping A[i] or A[(i + 1) % n] with any other element of the array increases the value of M(A). If such an element exists, make the swap.
Repeat steps 2 & 3 until the value M(A) cannot be improved.
This gives a local maxima for sure, but I am not sure whether this gives the global maxima.
Attempt 2: Checking for the existence of a permutation given neighbor constraints
Given input A[1..n], For i = 1..n and j = (i+1)..n compute x_ij = A[i] XOR A[j]
Compute the max(x_ij). Note that 2^p <= max(x_ij) < 2^(p+1) for some p.
Collect all x_ij such that x_ij >= 2^p. Note that this collection can be treated as a graph G with nodes {1, 2, .. n} and nodes i and j have an undirected edge between them if x_ij >= 2^p.
Check whether the graph G has a cycle which visits each node exactly once. If such a cycle exists, k = p. Otherwise, let p = p - 1, goto step 3.
This gives the correct answer, but note that in step 4 we are essentially checking whether a graph has a hamiltonian cycle which is a very hard problem.
Any hints or suggestions?
It is possible to solve this problem without going deep into graph theory.
Key inference
The property suggested by rich, is the key to solving this problem:
Following up on my comment: B1 Xor B2 < 2^K if and only if B1 and B2
agree on all but the K low order bits
Based on the above property, we only need to find the highest k for which there are at most n/2 occurrences of each unique higher order bits for every A[i].
In other words, amongst the group of values A[i] >> k, iff each of those values is repeated at most n/2 times, there exists a k-manipulative permutation with all the XOR values >= (2^k).
Why n/2
Suppose if you do have more than n/2 occurrences of any of the unique higher order bits, it is NOT possible to obtain a permutation B, with all the cyclic XORs being non-zero, i.e. there will be at least one B[i] XOR B[(i+1) % N] with all the higher order bits becoming zero, hence making M(B) < 2^k
Pseudocode
k = -1
for (bit = (MAX_BITS - 1) to 0) {
HashMap count
for (i = 0 to N - 1) {
higherOrderVal = A[i] >> bit
if (higherOrderVal exists in count) {
count[higherOrderVal] += 1
}
else {
count[higherOrderVal] = 1
}
}
isValid = true
for (element in count) {
if (element > N/2) {
isValid = false
break
}
}
if (isValid) {
k = bit
break
}
}
The time complexity for this solution is O(M * N) where M is the constant factor representing the maximum number of bits used to represent the numbers (32-bits, 64-bits, etc.), and N is the size of the input array A.
Following up on my comment: B1 Xor B2 < 2^K if and only if B1 and B2 agree on all but the K low order bits, so G has the very special structure of being complete multipartite, with partition labels consisting of all but the K low order bits. A complete multipartite graph is Hamiltonian if and only if there is no majority partition. Plug this fact into Attempt 2.
Greedy Approach #priority_queue
firstly insert all pairs xor value and consecutive index i and j ->pq.push(tuple(v[i]^v[j],i,j))
now pop the first maxm xor value and set the both index i and j
now again pop that maxm xor value which is comes from the i or j
this operation perform up to 1 to n
then return nth poped xor value

Resources