Divide and Conquer Patterns
Divide and Conquer প্যাটার্ন
1. The D&C Template
Divide the input into smaller subproblems, conquer each recursively, and combine. The recurrence T(n) = a · T(n/b) + f(n) determines complexity via Master Theorem (Module 05). Beyond merge/quick sort, D&C powers many of the fastest algorithms we know.
2. Closest Pair of Points — O(n log n)
Given n points in the plane, find the two with smallest Euclidean distance. Brute force is O(n²). The D&C version: sort by x, recurse on left and right halves to get min distances δ_L and δ_R, take δ = min. Then check the "strip" of points within δ of the dividing x-line — sorted by y, each point only needs to compare with the next 7 in the strip (a pigeon-hole geometric argument). Total O(n log n).
3. Karatsuba Multiplication — O(n^log₂3) ≈ O(n^1.585)
Multiply two n-digit numbers. Naive: O(n²). Split each into high and low halves: x = x_H·B + x_L, y = y_H·B + y_L. The naive expansion needs 4 sub-multiplications. Karatsuba's trick: compute three products P₁ = x_H · y_H, P₂ = x_L · y_L, P₃ = (x_H + x_L)(y_H + y_L), then x · y = P₁ · B² + (P₃ − P₁ − P₂) · B + P₂. Three sub-multiplications instead of four. T(n) = 3T(n/2) + n → O(n^log₂3) ≈ O(n^1.585).
#include <bits/stdc++.h>
using namespace std;
long long karatsuba(long long x, long long y) {
if (x < 10 || y < 10) return x * y;
int n = max(to_string(x).size(), to_string(y).size());
int m = n / 2;
long long B = pow(10, m);
long long xH = x / B, xL = x % B;
long long yH = y / B, yL = y % B;
long long P1 = karatsuba(xH, yH);
long long P2 = karatsuba(xL, yL);
long long P3 = karatsuba(xH + xL, yH + yL);
return P1 * B * B + (P3 - P1 - P2) * B + P2;
}
int main() {
cout << karatsuba(12345, 6789) << "\n";
cout << karatsuba(99999999, 99999999);
}
4. Strassen's Matrix Multiplication — O(n^log₂7) ≈ O(n^2.807)
Classical n × n matrix multiply: O(n³). Strassen splits each into 2 × 2 blocks and uses 7 sub-multiplications instead of 8 via clever combinations. Recurrence T(n) = 7T(n/2) + n² → O(n^2.807). The constant factor is large; in practice Strassen wins only beyond n ≈ 1000 and is rarely used in libraries (BLAS uses tuned naive O(n³)).
5. FFT — Polynomial Multiplication in O(n log n)
The Fast Fourier Transform evaluates a polynomial of degree n at n roots of unity in O(n log n) using D&C. Multiplying two polynomials becomes pointwise multiplication in the value domain. This is how big-int libraries push to O(n log n log log n), how convolution-based DP problems get faster, and the backbone of every signal-processing pipeline.
6. Practice Problems
-
Count inversions in an array using a modified merge sort in O(n log n).Inversions গুনুন — modified merge sort।
✨ Show Answer (উত্তর দেখুন)
Approach: during merge, when picking from the right half ahead of the left, count
mid − leftIdxas the number of inversions added. -
Majority element via D&C (Boyer-Moore is faster, but practice the recursion).Majority element — D&C।
✨ Show Answer (উত্তর দেখুন)
Approach: recurse on left and right halves; if both halves have the same majority, return it; otherwise count occurrences of each candidate in the full range — whichever exceeds half is the majority.
-
Maximum subarray sum via D&C (Kadane is O(n), but D&C is O(n log n)).Max subarray sum — D&C version।
✨ Show Answer (উত্তর দেখুন)
Approach: answer is max of (left half answer), (right half answer), (max suffix of left + max prefix of right). T(n) = 2T(n/2) + n → O(n log n). Kadane O(n) is better in practice but the D&C version is a great recursion-tree exercise.
-
Skyline problem — given building rectangles, find the outline.Skyline — D&C-এর সাহায্যে।
✨ Show Answer (উত্তর দেখুন)
Approach: recurse on halves to get two skylines; merge by walking left-to-right with the running max of both heights, emitting changes. O(n log n).
-
Closest pair of points on a small input — implement and verify against brute force.Closest pair — implementation।
✨ Show Answer (উত্তর দেখুন)
Approach: sort by x. recurse on halves; combine via the strip step. Stress-test on n = 100 against O(n²) brute force to verify correctness.
-
Why is Karatsuba O(n^1.585) and not O(n³)?Karatsuba complexity-এর গণনা।
✨ Show Answer (উত্তর দেখুন)
Answer: T(n) = 3T(n/2) + O(n). Master Theorem: a = 3, b = 2, c = log₂3 ≈ 1.585. f(n) = O(n) = O(n^(c−ε)) for some ε > 0 → Case 1 → T(n) = Θ(n^c) = Θ(n^1.585).
Summary — Module 33
Beyond merge sort, D&C unlocks closest-pair O(n log n), Karatsuba O(n^1.585), Strassen O(n^2.807), and the FFT-powered O(n log n) polynomial multiplication. Every algorithm here is a recurrence — Master Theorem reads off complexity at a glance.