Connected Component Range Query - algorithm

A graph consisting of n nodes, where there is an edge from 1 to 2, 2 to 3, 3 to 4, ........, n-1 to n.
Now, there is an array consisting of permutation of 1 to n and there are number of queries given based on array segments. Determine number of connected components formed by the nodes(indicated by the array elements) for the given segment. For e.g.,
Array : 4 5 3 2 1
Queries are : [1, 5], [1, 4], [2, 4]
For [1, 5], array elements are 1 2 3 4 5 and all are connected and forms a single connected component.
For [1, 4], array elements are 2 3 4 5, they also forms a single connected component.
For [2, 4], array elements are 2 3 5, so 2 and 3 forms a single component and 5 forms a single component so total of 2 connected components are there in [2, 4].

Since the graph has no cycles, the number of components in the subgraph is equal to the number of vertices minus the number of edges. The number of vertices is the length of the query interval. The number of edges can be found quickly by constructing an oracle for 2D orthogonal range counting queries on points that are (position of k in the permutation, position of k+1 in the permutation) for all k.

Related

given a positive number as a dividend, find out a subset from a given array, so that can get the minimum remainder

Here are some examples:
given number: 31
given array: [4, 5, 6, 7]
then the result subset will be [4] or [5] as 31 = 4 * 4 + 3 * 5, the remainder is 0,
but if given number: 31
given array: [4, 5, 6, 7, 8]
then the result subset will be [7, 8] as 31 = 3 * 8 + 1 * 7, the remainder is 0, which is the minimum one.
or if given number: 67
given array: [4, 5, 6, 9, 10, 12]
then the result subset will be [4, 9] as 67 = 7 * 9 + 1 * 4, the remainder is 0, which is the minimum one.
So what I want to ask is that if there is an algorithm to find out such subset from a given array, so that one can get the minimum remainder...
You can consider this task as variant of coin change problem (having sum and some coin nominals, choose the smallest number of coin to compose the sum).
I might be solved with dynamic programming:
Make array A of size sum, fill A[0] with 0, other entries with extreme large value.
For every coin C walk through array.
Intermediate sum i might be composed using coin C and sum i-C, so check
whether adding C to A[i-C] will diminish number of coin nominals used for A[i] and replace A[i] in positive case.
After all A[sum] will contain the smallest number of nominals. If it contain initial large value, scan lesser entries (A[sum-1] and so on).

How would I code an algorithm that does as follow?

I have three arrays of six red numbers ranging from 1 to 6. There can be multiple times the same number.
For example, [1, 4, 3, 3, 6, 2], [5, 5, 2, 1, 3, 4] and [2, 4, 3, 1, 1, 6]
The goal of the algorithm is to turn numbers blue in those arrays following these rules:
Every blue number has to be unique (1, 2, 3, 4, 5, 6)
Each array should have 2 blue numbers
The algorithm should warn me if it isn't possible to do so
In this example, the blue numbers could be (1, 4) in array one, (2, 5) in array two and (3, 6) in array three.
Is it realistic to code an algorithm that could do that? I'm looking for the logic that I could code to make it work.
You can reduce this problem to bipartite matching.
If we consider two sets of vertices, one for the arrays and one for the numbers, and make an edge between the array A and number n if n is an element of A, then we have a bipartite graph on which we can use any matching algorithm. Then, each match between an array and a number indicates that that number is blue in that array.
This only works for making a single number blue for each array, but can be expanded by adding every array as a vertex twice, thus getting two matches per array and therefore two blue numbers per array.

Is there a data structure for effective implementation of this encryption algorithm?

input -> alphabet -> output (index of a number in alphabet) -> new alphabet (the number moved to the begin of the alphabet):
3 -> [1, 2, 3, 4, 5] -> 3 -> [3, 1, 2, 4, 5]
2 -> [3, 1, 2, 4, 5] -> 3 -> [2, 3, 1, 4, 5]
1 -> [2, 3, 1, 4, 5] -> 3 -> [1, 2, 3, 4, 5]
1 -> [1, 2, 3, 4, 5] -> 1 -> [1, 2, 3, 4, 5]
4 -> [1, 2, 3, 4, 5] -> 4 -> [4, 1, 2, 3, 5]
5 -> [4, 1, 2, 3, 5] -> 5 -> [5, 4, 1, 2, 3]
input: (n - number of numbers in alphabet, m - length of text to be encrypted, the text)
5, 6
3 2 1 1 4 5
Answer: 3 2 1 1 4 5 -> 3 3 3 1 4 5
Is there any data structure or algorithm to make this efficiently, faster than O(n*m)?
I'd be appreciated for any ideas. Thanks.
Use an order statistics tree to store the pairs (1,1)...(n,n), ordered by their first elements.
Look up the translation for a character c by selecting the c-th smallest element of the tree and taking its second element.
Then update the tree by removing the node that you looked up and inserting it back into the tree with the first element of the pair set to -t, where t is the position in the message (or some other steadily decreasing counter).
Lookup, removal and insertion can be done in O(ln n) time worst-case if a self-balanced search tree (e.g. a red-black tree) is used as underlying tree structure for the order statistics tree.
Given that the elements for the initial tree are inserted in order, the tree structure can be build in O(n).
So the whole algorithm will be O(n + m ln n) time, worst-case.
You can further improve this for the case that n is larger than m, by storing only one node for any continuous range of nodes in the tree, but counting it for the purpose of rank in the order statistics tree according to the number of nodes there would normally be.
Starting then from only one actually stored node, when the tree is rearranged, you split the range-representing node into three: one node representing the range before the found value, one representing the range after the found value and one representing the actual value. These three nodes are then inserted back, in case of the range nodes only if they are non-empty and with the first pair element equal to the second and in case of the non-range node, with the negative value as described before. If a node with negative first entry is found, it is not split in this.
The result of this is that the tree will contain at most O(m) nodes, so the algorithm has a worst-time complexity of O(m ln min(n,m)).
Maybe a hashmap with letter/index pairs? I believe that element lookup in a hashmap usually O(1) most of the time, unless you have a lot of collisions (which is unlikely).

Combine lists to the least possible amount of 2-dimensional lists

Sorry for the bad description in the title.
Consider a 2-dimensional list such as this:
list = [
[1, 2],
[2, 3],
[3, 4]
]
If I were to extract all possible "vertical" combinations of this list, for a total of 2*2*2=8 combinations, they would be the following sequences:
1, 2, 3
2, 2, 3
1, 3, 3
2, 3, 3
1, 2, 4
2, 2, 4
1, 3, 4
2, 3, 4
Now, let's say I remove some of these sequences. Let's say I only want to keep sequences which have either the number 2 in position #1 OR number 4 in position #3. Then I would be left with these sequences:
2, 2, 3
2, 3, 3
1, 2, 4
2, 2, 4
1, 3, 4
2, 3, 4
The problem
I would like to re-combine these remaining sequences to the least possible amount of 2-dimensional lists needed to contain all sequences but no less or no more.
By doing so, the resulting 2-dimensional lists in this particular example would be:
list_1 = [
[2],
[2, 3],
[3, 4]
]
list_2 = [
[1],
[2, 3],
[4]
]
In this particular case, the resulting lists can be thought out. But how would I go about if there were thousands of sequences yielding hundereds of 2-dimensional lists? I have been trying to come up with a good algorithm for two weeks now, but I am getting nowhere near a satisfying result.
Divide et impera, or divide and conquer. If we have a logical expression, stating that the value at position x should be a or the value at position y should be b, then we have 3 cases:
a is the value at position x and b is the value at position y
a is the value at position x and b is not the value at position y
a is not the value at position x and b is the value at position y
So, first you generate all your scenarios, you know now that you have 3 scenarios.
Then, you effectively separate your cases and handle all of them in a sub-routine as they were your main tasks. The philosophy behind divide et imera is to reduce your complex problem into several similar, but less complex problems, until you reach triviality.

Parallel algorithm for set intersections

I have n-sets (distributed on n-ranks) of data which represents the nodes of a mesh and I wanted to know an efficient parallel algorithm to find the intersection of these sets, i.e., the common nodes. An intersection is defined as soon as any 2 sets share a node.
For example;
Input:
Rank 0: Set 1 - [0, 1, 2, 3, 4]
Rank 1: Set 2 - [2, 4, 5, 6]
Rank 2: Set 3 - [0, 5, 6, 7, 8]
Implement Parallel Algorithm --> Result: (after finding intersections)
Rank 0: [0, 2, 4]
Rank 1: [2, 4, 5, 6]
Rank 2: [0, 5, 6]
The algorithm needs to be done on n-ranks with 1 set on each rank.
You should be able to this fast O(N), in parallel, with hash tables.
For each set S_i, for each member m_x (all of which can be done in parallel), put the set member into a hash table associated with the set name, e.g., . Anytime you get a hit in the hash table on m_x from set S_j, you now have the corresponding set number S_i, and you know immediately that S_i intersects S_j. You can put m_x in the derived intersection sets.
You need a parallel-safe hash table. That's easy; lock the buckets during updates.
[Another answer suggested sorting the sets. With most sort algorithms, would be O(N ln N) time, not as fast].

Resources