Combinations of a sequence with any adjacent product no more than a given number - algorithm

I was wondering whether there is an analytic solution or recursive solution of the combination calculation of natural number sequence with length X, where the multiplications of any adjacent numbers in the sequence is no more than Y?
For example when X = 3, Y = 3, the sequences are (1,1,1)(1,1,2)(1,1,3)(1,2,1)(2,1,1)(1,3,1)(3,1,1),(3,1,2)(2,1,3)(3,1,3)(2,1,2).
I know when X = 2, such combination is
Y + [Y/2] + [Y/3] + ... +[Y/Y]
how to recursively derive from X to X+1 then? Or is there some direct expression of the solution?

Let's P(Y, X, K) is number of combinations with length X, ending with K. Then
P(Y, X + 1, M) = Sum(k=1..[Y/M] P(Y, X, K))
with starting point:
P(Y, 1, K = 1..Y) = 1

Related

Algorithm for selecting the differents pair

May be somebody can help me with it.
So, I have a set of pairs x0-y0, x1-y1, etc.
And always x[i]<y[i]. Thus I need a function (or algorithm) for every pair, so
F(x[i],y[i]) = result[i], and each result for a particular pair must be an integer unique value.
Let M = max(y) - min(y) + 1, then use the formula:
F(x, y) = x * M + y
Remarks:
You don't have to use the exact maximum and minimum, you can use an upperbound and a lowerbound, M = U - L + 1 with U larger than all y and L smaller than all y;
Of course you could do it the other way around instead, with K = max(x) - min(x) + 1, and F(x, y) = y * K + x;
When using a finite integer type, be careful with overflow, for instance if x and y both have values larger than 46340, then F(x, y) won't fit in a 32-bit signed integer.

Number of pair in array that satisfy Bitwise Equation

I found this problem in a contest. The question is:
You are given an array of N non-negative integers (A1, A2, A3,..., An) and an integer M. Your task is to find the number of unordered pairs of array elements (X,Y) that satisfies the following bitwise equation:
2 * set_bits(X|Y) = M + set_bits(X ⊕ Y)
Note:
set_bits(n) represents the number of ones in the binary represenataion of an integer n.
X|Y represents the bitwise OR of integer X and Y.
X ⊕ Y represents the bitwise XOR of integer X and Y.
The unordered pair of array elements is pair (Ai, Aj) where 1 ≤ i < j ≤ N.
Print the number of unordered pairs of array elements that satisfy the above bitwise equation.
Sample Input 1:
N=4 M=2
arr = [3, 0, 4, 5]
Sample Output: 2
2 pairs are (3,0) and (0,5)
Sample Input 2:
N=8 M=2
arr = [3, 0, 4, 5, 6, 8, 1, 8]
Sample Output: 9
Is there any other way except brute force to solve this equation?
A solution with time complexity O(n) exists if the time complexity of set_bits is O(1).
First, we are going to rephrase the condition (the bitwise equation) a bit. Assume a pair of elements (X, Y) is given. Let c_01 represent the number of digits where X is 0 but Y is 1, c_10 represent the number digits where X is 1 and Y is 0, and c_11 represent the number of digits where X and Y are 1. For example, when X=5 and Y=1 (X=101, Y=001), c_01 = 0, c_10 = 1, c_11 = 1. Now, the condition can be rewritten as
2 * (c_01 + c_10 + c_11) = M + (c_01 + c_10)
because set_bits(X|Y) is equal to c_01 + c_10 + c_11 and set_bits(X^Y) is equal to c_01 + c_10.
We can reorder the equation into
c_01 + c_10 + 2*c_11 = M
by moving the term on the right to the left side. Now, realize that set_bits(X) = c_10 + c_11. Applying this information on the equation we get
c_01 + c_11 = M - set_bits(X)
Now, also realize that set_bits(Y) = c_01 + c_11. The equation becomes
set_bits(Y) = M - set_bits(X)
or
set_bits(X) + set_bits(Y) = M
The problem has turned into counting the number of pairs such that the number of set bits in the first element plus the number of set bits in the second element is equal to M. This can be done in linear time assuming you can compute set_bits in constant time.

Finding distinct pairs {x, y} that satisfies the equation 1/x + 1/y = 1/n with x, y, and n being whole numbers

The task is to find the amount of distinct pairs of {x, y} that fits the equation 1/x + 1/y = 1/n, with n being the input given by the user. Different ordering of x and y does not count as a new pair.
For example, the value n = 2 will mean 1/n = 1/2. 1/2 can be formed with two pairs of {x, y}, whcih are 6 and 3 and 4 and 4.
The value n = 3 will mean 1/n = 1/3. 1/3 can be formed with two pairs of {x, y}, which are 4 and 12 and 6 and 6.
The mathematical equation of 1/x + 1/y = 1/n can be converted to y = nx/(x-n) where if y and x in said converted equation are whole, they count as a pair of {x, y}. Using said converted formula, I will iterate n times starting from x = n + 1 and adding x by 1 per iteration to find whether nx % (x - n) == 0; if it yields true, the x and y are a new distinct pair.
I found the answer to limit my iteration by n times by manually computing the answers and finding the number of repetitions 'pattern'. x also starts with n+1 because otherwise, division by zero will happen or y will result in a negative number. The modulo operator is to indicate that the y attained is whole.
Questions:
Is there a mathematical explanation behind why the iteration is limited to n times? I found out that the limit of iteration is n times by doing manual computation and finding the pattern: that I only need to iterate n times to find the amount of distinct pairs.
Is there another way to find the amount of distinct pairs {x, y} other than my method above, which is by finding the VALUES of distinct pairs itself and then summing the amount of distinct pair? Is there a quick mathematical formula I'm not aware of?
For reference, my code can be seen here: https://gist.github.com/TakeNoteIAmHere/596eaa2ccf5815fe9bbc20172dce7a63
Assuming that x,y,n > 0 we have
Observation 1: both, x and y must be greater than n
Observation 2: since (x,y) and (y,x) do not count as distinct, we can assume that x <= y.
Observation 3: x = y = 2n is always a solution and if x > 2n then y < x (thus no new solution)
This means the possible values for x are from n+1 up to 2n.
A little algebra convers the equation
1/x + 1/y = n
into
(x-n)*(y-n) = n*n
Since we want a solution in integers, we seek integers f, g so that
f*g = n*n
and then the solution for x and y is
x = f+n, y = g+n
I think the easiest way to proceed is to factorise n, ie write
n = (P[1]^k[1]) * .. *(P[m]^k[m])
where the Ps are distinct primes, the ks positive integers and ^ denotes exponentiation.
Then the possibilities for f and g are
f = P[1]^a[1]) * .. *(P[m]^a[m])
g = P[1]^b[1]) * .. *(P[m]^b[m])
where the as and bs satisfy, for each i=1..m
0<=a[i]<=2*k[i]
b[i] = 2*k[i] - a[i]
If we just wanted to count the number of solutions, we would just need to count the number of fs, ie the number of distinct sequences a[]. But this is just
Nall = (2*k[1]+1)*... (2*[k[m]+1)
However we want to count the solution (f,g) and (g,f) as being the same. There is only one case where f = g (because the factorisation into primes is unique, we can only have f=g if the a[] equal the b[]) and so the number we seek is
1 + (Nall-1)/2

Counting subarray have sum in range [L, R]

I am solving a competitive programming problem, it was described like this:
Given n < 10^5 integer a1, a2, a3, ..., an and L, R. How many
subarrays are there such that sum of its element in range [L, R].
Example:
Input:
n = 4, L = 2, R = 4
1 2 3 4
Output: 4
(4 = 4, 3 = 1 + 2 = 3, 2 = 2)
One solution I have is bruteforce, but O(n^2) is too slow. What data structures / algorithms should I use to solve this problem efficiently ?
Compute prefix sums(p[0] = 0, p[1] = a1, p[2] = a1 + a2, ..., p[n] = sum of all numbers).
For a fixed prefix sum p[i], you need to find the number of such prefix sums p[j] that j is less than i and p[i] - R <= p[j] <= p[i] - L. One can do it in O(log n) with treap or another balanced binary search tree.
Pseudo code:
treap.add(0)
sum = 0
ans = 0
for i from 1 to n:
sum += a[i]
left, right = treap.split(sum - R)
middle, right = right.split(sum - L)
ans += middle.size()
merge left, middle and right together
treap.add(sum)
We can do it in linear time if the array contains positive numbers only.
First build an array with prefix sum from left to right.
1. Fix three pointers, X, Y and Z and initialize them with 0
2. At every step increase X by 1
3. While sum of numbers between X and Y are greater than R keep increasing Y
4. While sum of numbers between X and Z are greater than or equal to L, keep increasing Z
5. If valid Y and Z are found, add Z - Y + 1 to result.
6. If X is less than length of the array, Go to step 2.

3SUM problem (finding triplets) in better than O(n^2)

Consider the following problem:
Given an unsorted array of integers, find all triplets that satisfy x^2 + y^2 = z^2.
For example if given array is 1, 3, 7, 5, 4, 12, 13, the answer should be 5, 12, 13 and 3, 4, 5
I suggest the below algorithm with complexity O(n^2):
Sort the array in descending order, O(nlogn)
square each element, O(n)
Now it reduces to the problem of finding all triplets(a,b,c) in a sorted array such that a = b+c.
The interviewer was insisting on a solution better than O(n^2).
I have read 3SUM problem on Wikipedia, which emphasizes problem can be solved in O(n+ulogu) if numbers are in range [-u,u] assuming the array can be represented as a bit vector. But I am not able to get a clear picture of further explanations.
Can someone please help me in understanding what is going on with a nice example?
First of all. Finding all triplets in worst case is O(n^3). Suppose you have n=3k numbers. K of them are 3, k are 4 and k are 5.
3,....,3,4,....,4,5,.....5
There are k^3 = n^3/27 = O(n^3) such triplets. Just printing them takes O(n^3) time.
Next will be explaining of 3SUM problem in such form:
There are numbers s_1, ..., s_n each of them in range [-u;u]. How many triplets a,b,c there are that a+b=c?
transforming. Get 2*u numbers a_-u, ..., a_0, a_1, ... a_u. a_i is amount of numbers s_j, that s_j = i. This is done in O(n+u)
res = a_0 * sum(i=-u..u, i=/=0, C(a_i, 2)) + C(a_0,3) a_0 = 0
Build a polynom P(x) = sum(i = -u...u, a_i*x^(i+u).
Find Q(x) = P(x)*P(x) using FFT.
Note that Q(x) = sum(i=-2u..2u, b_i*x^(i+2*u)), where b_i is number of pairs s_u,s_k that s_u+s_k = i (This includes using same number twice).
For all even i do b_i = b_i - a_(i/2). This will remove using same number twice.
Sum all b_i*a_i/2 - add this to res.
Example: to be more simple, I will assume that range for numbers is [0..u] and won't use any +u in powers of x.
Suppose that we have numbers 1,2,3
- a_0 = 0, a_1 = 1, a_2 = 1, a_3 = 1
res = 0
P(x) = x + x^2 + x^3
Q(x) = x^2 +2x^3+3x^4+2x^5+x^6
After subtracting b_2 = 0, b_3 = 2, b_4 = 2, b_5 = 2, b_6 = 0
res += 0*1/2 + 2*1/2 + 2*0/2 + 2*0/2 + 6*0/2 = 1
Another possibility (who can fathom the mind of an interviewer?) would be to rewrite the equation as:
x^2 + y^2 = z^2
x^2 = z^2 - y^2 = (z-y)(z+y)
If we knew the prime factorisation of x^2 then we could simply iterate through all possible factorisations into a pair of numbers p,q (with p < q) and compute
x^2 = p.q = (z-y)(z+y)
p+q = (z-y)+(z+y) = 2z
q-p = (z+y)-(z-y) = 2y
z = (p+q)/2
y = (q-p)/2
So given a factorisation x^2=p.q we can work out the z and y values. By putting all the integer values into a set we can then check each possible answer in time O(1) (per check) by looking to see if those z,y values are in the array (taking care that negative values are also detected).
Wikipedia says that a randomly chosen integer has about log(n) divisors so this should take about n.log(n) assuming you can do the factorisation fast enough (e.g. if you knew all the integers were under a million you could precompute an array of the smallest factor for each integer).

Resources