Computational Geometry & Number Theory Essentials
জ্যামিতি ও সংখ্যা তত্ত্ব
1. Cross Product & Orientation
For three points A, B, C, the cross product
(B − A) × (C − A) = (Bx − Ax)(Cy − Ay) − (By − Ay)(Cx − Ax)
tells us:
- > 0 → counter-clockwise turn (left turn)
- < 0 → clockwise turn (right turn)
- = 0 → collinear
This single primitive powers convex hull, polygon area, segment intersection, and point-in-polygon tests.
2. Convex Hull — Andrew's Monotone Chain
Sort points by (x, y). Build the lower hull left-to-right, popping while the turn isn't a counter-clockwise. Build the upper hull right-to-left similarly. Concatenate. O(n log n) with sorting; O(n) for the hull walk itself.
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
struct P { ll x, y; };
ll cross(P O, P A, P B) {
return (A.x - O.x) * (B.y - O.y) - (A.y - O.y) * (B.x - O.x);
}
vector<P> hull(vector<P> pts) {
sort(pts.begin(), pts.end(), [](P a, P b) {
return a.x < b.x || (a.x == b.x && a.y < b.y);
});
int n = pts.size(), k = 0;
vector<P> H(2*n);
// lower hull
for (int i = 0; i < n; i++) {
while (k >= 2 && cross(H[k-2], H[k-1], pts[i]) <= 0) k--;
H[k++] = pts[i];
}
// upper hull
for (int i = n - 2, t = k + 1; i >= 0; i--) {
while (k >= t && cross(H[k-2], H[k-1], pts[i]) <= 0) k--;
H[k++] = pts[i];
}
H.resize(k - 1);
return H;
}
int main() {
vector<P> pts = {{0,0},{2,0},{2,2},{0,2},{1,1},{3,1}};
for (P p : hull(pts)) cout << "(" << p.x << "," << p.y << ") ";
}
3. Sieve of Eratosthenes — Primes up to N in O(N log log N)
#include <bits/stdc++.h>
using namespace std;
int main() {
int N = 100;
vector<bool> isPrime(N + 1, true);
isPrime[0] = isPrime[1] = false;
for (int i = 2; (long long)i * i <= N; i++)
if (isPrime[i])
for (int j = i * i; j <= N; j += i) isPrime[j] = false;
for (int i = 2; i <= N; i++) if (isPrime[i]) cout << i << " ";
}
4. GCD & Modular Exponentiation
gcd(a, b) = gcd(b, a mod b), base gcd(a, 0) = a. Modular
exponentiation by binary expansion: a^n mod m in O(log n).
#include <bits/stdc++.h>
using namespace std;
long long gcd(long long a, long long b) { return b == 0 ? a : gcd(b, a % b); }
long long powmod(long long a, long long n, long long m) {
long long r = 1 % m;
a %= m;
while (n > 0) {
if (n & 1) r = r * a % m;
a = a * a % m;
n >>= 1;
}
return r;
}
int main() {
cout << gcd(462, 1071) << "\n";
cout << powmod(2, 100, 1000000007LL);
}
5. Modular Inverse via Fermat
For a prime p, a^(p−1) ≡ 1 (mod p) ⇒ a^(p−2) is the modular
inverse of a. So inv(a) = powmod(a, p − 2, p). Useful for computing nCr mod p,
modular division, and modular linear systems.
6. Practice Problems
-
Test if a point is inside a convex polygon.Convex polygon-এ point inside কিনা।
✨ Show Answer (উত্তর দেখুন)
Approach: for each edge AB, check the sign of cross(A, B, P). If all signs are the same (all left or all right), the point is inside.
-
Determine if two segments intersect (general position).দুই segment intersect করে কিনা।
✨ Show Answer (উত্তর দেখুন)
Approach: AB intersects CD iff cross(A, B, C) and cross(A, B, D) have opposite signs and cross(C, D, A) and cross(C, D, B) have opposite signs. Handle collinear with bounding-box overlap.
-
Count primes ≤ 10⁶ using the sieve.10⁶-এর মধ্যে prime সংখ্যা।
✨ Show Answer (উত্তর দেখুন)
Answer: 78498. Sieve and count true entries.
-
Compute nCr mod p (p prime) using factorials and Fermat inverse.nCr mod p — Fermat inverse।
✨ Show Answer (উত্তর দেখুন)
Approach: precompute fact[i] mod p and invFact[i] = powmod(fact[i], p-2, p). Then nCr = fact[n] * invFact[r] % p * invFact[n-r] % p.
-
Linear sieve — compute the smallest prime factor of every i ≤ N.Smallest prime factor sieve।
✨ Show Answer (উত্তর দেখুন)
Approach: standard linear sieve. spf[i] is set when i is first marked composite — by its smallest prime factor.
-
Maximum points on a single line, given n points.এক লাইনে maximum point।
✨ Show Answer (উত্তর দেখুন)
Approach: for each anchor point, count slopes (dy / dx reduced by gcd) using a hash map. Update best across all anchors.
-
Polygon area from a list of vertices using the shoelace formula.Polygon area — shoelace।
✨ Show Answer (উত্তর দেখুন)
Formula: 2·area = |Σ (x_i · y_{i+1} − x_{i+1} · y_i)|. Sum cross products of consecutive points (cyclically) and halve the absolute value.
Summary — Module 39
Cross product is the orientation primitive of all 2D geometry — convex hull, point-in-polygon, segment intersection. The sieve produces all primes up to N in O(N log log N). Modular exponentiation gives a^n mod p in O(log n) — and via Fermat's little theorem, modular inverses for free. Light math, heavy contest leverage.