Skip to content

Commit c18ff68

Browse files
committed
data structure and algorithms - sherlocks-array-merging-algorithm (dynamic programming)
1 parent 1be9f05 commit c18ff68

File tree

3 files changed

+61
-13
lines changed

3 files changed

+61
-13
lines changed

Diff for: competitive_prog/cp/cp_code/merging-communities.MD

+2-2
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,11 @@ Q 2
7373
+ The M 2 3 query merges the communities of Persons 2 and 3.
7474
+ The Q 3 and Q 2 queries show that Persons 3 and 2 now belong to a community of size 3.
7575

76-
This problem involves efficiently managing and querying dynamic community sizes, often tackled using data structures such as Disjoint Set Union (DSU) or Union-Find.
77-
7876

7977
## 🦩 Solution:
8078

79+
This problem involves efficiently managing and querying dynamic community sizes, often tackled using data structures such as Disjoint Set Union (DSU) or Union-Find.
80+
8181
To solve the problem of merging communities and querying their sizes, we can utilize the Disjoint Set Union (DSU) data structure, also known as Union-Find. This structure is efficient for operations that involve merging sets and finding the representative or size of sets. Here's a detailed step-by-step solution and the corresponding C++ STL code:
8282

8383
### Step-by-Step Solution :

Diff for: competitive_prog/cp/cp_code/sherlocks-array-merging-algorithm.MD

+58-11
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ Explanation 1 :
114114

115115
The only distinct possible collection is V = {[2, 1]}, so we print the result of 1mod(10^9+7) = 1 as our answer.
116116

117+
### Solution :
118+
117119
```cpp
118120
#include <iostream>
119121
#include <cstring>
@@ -188,6 +190,9 @@ int main() {
188190
return 0;
189191
}
190192
```
193+
### Code Walkthrough :
194+
195+
This is a problem from Dynamic Programming.
191196
192197
### Header Files and Namespaces:
193198
@@ -238,12 +243,16 @@ int countWays(int last, int pos) {
238243
}
239244
```
240245
241-
+ This function computes the number of ways to create collection V recursively.
242-
+ `last` represents the last element used in the previous collection.
243-
+ `pos` represents the current position in the array.
244-
+ If `pos` exceeds `n`, it returns the inverse factorial of `last`.
245-
+ The function uses memoization to store already computed values in the `dp` array.
246-
+ It iterates over possible positions to split the array and calculates the number of ways recursively.
246+
+ `Parameters`: `last` is the length of the last segment considered, `pos` is the current position in the array `m`.
247+
+ `Base Case`: If `pos` exceeds `n`, return the inverse factorial of `last` (no more elements to consider).
248+
+ `Memoization`: If the result for `dp[last][pos]` is already computed, return it.
249+
+ `Recursive Calculation`: Iterate over possible next positions (`i`) to split the array. For each position `i`, the function makes a recursive call to `countWays` with the new segment length `i - pos + 1` and the new starting position `i + 1`.
250+
+ Calculate the number of ways recursively.
251+
+ Multiply with factorial and inverse factorial for proper combination counting, ensuring results are modulo `MOD`.
252+
+ `factorial[i - pos + 1]`: Factorial of the length of the new segment.
253+
+ `countWays(i - pos + 1, i + 1)`: Recursive call for the next segment.
254+
+ `inverse_factorial[last - (i - pos + 1)]`: Inverse factorial of the remaining length after considering the new segment.
255+
+ `Memoize and Return Result`: Store the result in `dp` and return it.
247256
248257
### Main Function:
249258
@@ -290,9 +299,47 @@ int main() {
290299
}
291300
```
292301

293-
+ The main function reads the input array `m` and calculates the right boundaries of increasing sequences.
294-
+ It precomputes the factorial and inverse factorial arrays.
295-
+ Then, it initializes the `dp` array with -1 using `memset`.
296-
+ Finally, it computes the answer using the `countWays` function and outputs the result.
302+
#### `Input Reading`:
303+
304+
+ Read the integer `n` (size of array `m`).
305+
+ Read the elements of the array `m`.
306+
307+
#### `Right Boundaries Calculation`:
308+
309+
+ Initialize `right_bound[n]` to `n`.
310+
+ Traverse the array from the end to the beginning:
311+
+ If the next element is greater, propagate the right boundary.
312+
+ Otherwise, set the right boundary to the current index.
313+
314+
#### `Factorials and Inverse Factorials Precomputation`:
315+
316+
+ Compute the factorials modulo `MOD`.
317+
+ Compute the modular inverses of the factorials using the property:
318+
+ `inverse_factorial[i] = ((-1 * (MOD / i) * inverse_factorial[MOD % i]) % MOD + MOD) % MOD`.
319+
320+
Inverse Factorial using Fermat’s Little Theorem.
321+
+ Ensure results are modulo `MOD`.
322+
323+
#### `Initialize dp Array`:
324+
325+
+ Set all elements of `dp` to `-1` using `memset`.
326+
327+
#### `Compute the Answer`:
328+
329+
+ Iterate over possible initial segment lengths.
330+
+ Use the `countWays` function to compute the number of valid ways for each segment length.
331+
+ Sum the results, ensuring the sum is modulo `MOD`.
332+
333+
#### `Output the Result`:
334+
335+
+ Print the computed answer.
336+
337+
The `countWays` function calculates the number of ways to split the array starting from a given position into increasing subsequences. It uses:
338+
339+
+ `Recursion`: To explore all possible ways to split the array.
340+
+ `Memoization`: To store already computed results for efficiency.
341+
+ `Factorials and Inverse Factorials`: To correctly handle combinations under modular arithmetic constraints.
342+
343+
This approach ensures that all possible partitions are considered efficiently, and the results are computed accurately within the constraints of the problem.
297344

298-
This code efficiently calculates the number of different ways to create collection V, satisfying the conditions specified in the problem statement.
345+
This code efficiently calculates the number of different ways to create collection V, satisfying the conditions specified in the problem statement.

Diff for: competitive_prog/dsalgo.MD

+1
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ Data Structure [[NOTES](./code/ds.MD)]</th>
9797
+ Other Structures
9898
+ Set Structures
9999
+ Sets and multisets [[vid](https://youtu.be/7mx2BasNK0w?si=PPzqesmxu78RHNZw)]
100+
+ Disjoint Set Union (DSU) / Union Find [[blog](https://cp-algorithms.com/data_structures/disjoint_set_union.html), [blog 2](https://www.geeksforgeeks.org/union-by-rank-and-path-compression-in-union-find-algorithm/), [Union Find Path Compression](https://youtu.be/VHRhJWacxis?si=jskV2H3isBtwS5DU)]
100101
+ Maps [[vid](https://youtu.be/gUrfXZ0hqoA?si=9_5vrpXUmHOQKnH2)]
101102
+ Priority Queues [[vid](https://youtu.be/wptevk0bshY?si=o6XiXrfPcdlXffP6)]
102103
+ Policy-Based Sets

0 commit comments

Comments
 (0)