Finding all Coprime subset upto a number N - algorithm

Suppose I have numbers 1 to N and I want to divide them into subsets based on following criteria:
Each number can be present in only 1 subset.
The elements of the subsets must be mutually coprime.
Minimizing the total number of subsets.
My approach to it is by finding all primes up to N using Sieve of Eratosthenes and then dividing them accordingly in subsets. For example for N=5, I can have two subsets at minimum {1,2,3,5} and {4}. But I am unsure how to distribute the elements in subsets so that each subset has mutually coprime elements.
Here's my approach stepwise:
Set 1: {all primes up to N}
Set 2: {2k,3k,5k...pk} where p is a prime and pk < N.
For different values of k, we can form different sets till 2k< N.
Rest of the elements
The problem is how to get elements in step 3 to be mutually coprime in the subset
Can someone suggest a better approach on how to implement it and flaws in my logic?

It seems like it's a trick question. No two even numbers can be in the same subset, so the minimal number of subsets is floor(n/2)
If n is even, you can easily achieve the bound with subsets {2i+1, 2i+2}. For n odd, you do the same, but put {n-2, n-1, n} in the last subset. Note that adjacent numbers are always coprime, and n,n-2 are coprime when n is odd.

Related

Find permutations, that totally change the set of cumulative sums

I've got the following problem:
Let N be a set of natural numbers with length n.
Let S be the set of all cumulative sums, where a cumulative sum is the sum of the first k elements of a set.
Now, given N, permutate its elements, so that S_i contains no element of S (i refers to the ith permutation).
Find as many of these permutations, as possible.
Could anyone help me with an idea? You don't have to give an algorithm, just an approach.
Obviously, the last element in S_i (or S) is the sum of all elements. Regardless of how you permute the elements, this element will always be in the list (btw, calling N or S a set is syntactically wrong if you refer to an order).
Therefore, there is no permutation of N having S_i disjoint from S.

Count the total number of subsets that don't have consecutive elements

I'm trying to solve pretty complex problem with combinatorics and counting subsets. First of all let's say we have given set A = {1, 2, 3, ... N} where N <= 10^(18). Now we want to count subsets that don't have consecutive numbers in their representation.
Example
Let's say N = 3, and A = {1,2,3}. There are 2^3 total subsets but we don't want to count the subsets (1,2), (2,3) and (1,2,3). So in total for this question we want to answer 5 because we want to count only the remaining 5 subsets. Those subsets are (Empty subset), (1), (2), (3), (1,3). Also we want to print the result modulo 10^9 + 7.
What I've done so far
I was thinking that this should be solved using dynamical programming with two states (are we taking the i-th element or not), but then I saw that N could go up to 10^18, so I was thinking that this should be solved using mathematical formula. Can you please give me some hints where should I start to get the formula.
Thanks in advance.
Take a look at How many subsets contain no consecutive elements? on the Mathematics Stack Exchange.
They come to the conclusion that the number of non-consecutive subsets in the set {1,2,3...n} is the fib(n+2) where fib is the function computing the Fibonacci sequence for the number n+2. Your solution to n=3 conforms to this solution. If you can implement the Fibonacci algorithm, then you can solve this problem, but solving the question for a number as large as 10^18 will still be a challenge.
As mentioned in the comments here, you can check out the fast doubling algorithm on Hacker Earth.
It will find Fibonacci numbers in O(log n).

Algorithm to calculate permutations

I'm aware of Heap's algorithm to calculate permutations of a given sequence, but what if I wanted to calculate the permutations of a k-elements subset for a given sequence N?
The solution I'm thinking of this time is a backtracking one, but it would need to generate a new sequence of sub-elements each time deleting one and recursively calling the permutation function. This sounds expensive and I would like to know if there's a better solution
Use an algorithm to generate combinations of size K from the set of N.
(Pick any from the SO question: Algorithm to return all combinations of k elements from n).
Using the result, apply Heap's Algorithm to create all permutations of this k-element subset (or another Algorithm to generate all possible permutations of a list).
Generate the next subset of size K and repeat (steps 1 and 2) until all subsets of size K have been enumerated.

Find triplets in an array whose sum is some integer X

Given a sorted array[1..n] where each element ranging from 1 to 2n. Is there a way to find triplet whose sum is given integer x. I know O(n^2) solution. Is there any algorithm better than n^2 ones.
It is possible to achieve an O(n log n) time complexity using that fact the maximum value of each element is O(n).
For each 1 <= y <= 4 * n, let's find the number of pairs of elements that sum up to y. We can create a polynomial of 2 * n power, where the i-th coefficient of this polynomial is the number of occurrences of the number i in the given array. Now we can find the square(I'll call it s) of this polynomial in O(n log n) time using Fourier's Fast Transform. The i-th coefficient of s is exactly the number of pairs of elements that sum up to i.
Now we can iterate over the given array. Let's assume that the current element is a. Then we just need to check the number of pairs that sum up to X - a. We have already done it in the step 1).
If all triplets must consist of different elements, we need to subtract the number of such triplets that sum up to X but contain duplicates. We can do it in O(n log n) time, too(for triplets that consist of three equal elements, we just need to subtract the number of occurrences of X / 3 in the given array. For triplets with one duplicate, we can just iterate over the element that is repeated twice(a) and subtract the number of occurrences of X - 2 * a).
If we need to find a triplet itself, not just count them, we can do the following:
Count the number of triplets and pairs as suggested above.
Find such an element that there is a pair that sums up to X with it.
Find two elements that sum up to the desired sum of this pair.
All these steps can be accomplished in linear time(using the fact that all sums are O(n)).
Your problem is apparently the non-zero sum variant of the 3SUM problem.
Because you know the possible range of the integers beforehand, you can achieve lower bounds than the general case, according to the second paragraph of the article:
When the elements are integers in the range [-N, ..., N], 3SUM can be
solved in O(n + N log N) time by representing the input set S as a
bit vector, computing the set S + S of all pairwise sums as a discrete
convolution using the Fast Fourier transform, and finally comparing
this set to -S.
In your case, you would have to pre-process the array by subtracting n + X/3 before running the algorithm.
One thing to note is that the algorithm assumes you're working with a set of numbers, and I'm not sure what (if any) implications there may be on running time if your array may include duplicates.

How to generate random permutations fast

I read a question in an algorithm book:
"Given a positive integer n, choose 100 random permutations of [1,2,...,n],..."
I know how to generate random permutations with Knuth's algorithm. but does there exist any fast algorithms to generate large amount of permutations ?
Knuth shuffles require you to do n random swaps for a permutation of n elements (see http://en.wikipedia.org/wiki/Random_permutation#Knuth_shuffles) so the complexity is O(n) which is about the best you can expect if you receive a permutation on n elements.
Is this causing you a practical problem? If so, perhaps you could look at what you are doing with all those permutations in practice. Apart from simply getting by on less, you could think about deferring generating a permutation until you are sure you need it. If you need a permutation on n objects but only look at k of those n objects, perhaps you need a scheme for generating only those k elements. For small k, you could simply generate k random numbers in the range [0, n) at random, repeating generations which return numbers which have already come up. For small k, this would be unlikely.
There exist N! permutations of numbers from 1 to N. If you sort them lexicographically, like in a dictionary, it's possible to construct permutation knowing it order in a list of sorted permutations.
For example, let N=3, lexicographically sorted list of permutations is {123,132,213,231,312,321}. You generate number between 1 and 3!, for example 5. 5-th permutaion is 312. How to construct it?
Let's find the 1-st number of 5-th permutation. Let's divide permutations into blocks, criteria is 1-st number, I means such groups - {123,132},{213,231},{312,321}. Each group contains (n-1)! elements. The first number of permutation is the block number. 5-th permutation is in ceil(5/(3-1)!)=3 block. So, we've just found the first number of 5-th permutation it's 3.
Now I'm looking for not 5-th but (5-(n-1)!*(ceil(5/2)-1))=5-2*2=1-th permutation in
{3,1,2},{3,2,1}. 3 is determined and the same for all group members, so I'm actually searching for 1-th permutation in {1,2},{2,1} and N now is 2. Again, next_num = ceil(1/(new_N-1)!) = 1.
Continue it N times.
Hope you got the idea. Complexity is O(N) - because you constructing permutation elements one by one with arithmetical tricks.
UPDATE
When you got next number by arithmetical opearions you should also keep used array and instead of X take X-th unused Complexity becomes NlogN because logN needed for getting X-th unused element

Resources