Inclusion-Exclusion
The two-set case
To count the elements in either of two sets, add their sizes and subtract the overlap, which would otherwise be counted twice.
|A ∪ B| = |A| + |B| - |A ∩ B|
How many integers from 1 to N are divisible by 3 or 5?
long countDivisible(long n, long a, long b) {
return n / a + n / b - n / lcm(a, b);
}
n / a counts multiples of a without a loop, and the multiples of both are exactly the multiples of their least common multiple. Using a * b instead of the LCM is correct only when a and b share no factors.
Three sets and beyond
With three sets, subtracting the pairwise overlaps removes the triple overlap too many times, so it must be added back.
|A ∪ B ∪ C| = |A| + |B| + |C|
- |A∩B| - |A∩C| - |B∩C|
+ |A∩B∩C|
The pattern continues: add the single sets, subtract pairs, add triples, subtract quadruples. A term’s sign is positive when it involves an odd number of sets and negative when even.
Iterating over subsets
For k sets, enumerate all 2k subsets with a bitmask and let the popcount decide the sign.
static long unionSize(long n, long[] values) {
int k = values.length;
long total = 0;
for (int mask = 1; mask < (1 << k); mask++) {
long combined = 1;
for (int i = 0; i < k; i++) {
if ((mask & (1 << i)) != 0) {
combined = lcm(combined, values[i]);
if (combined > n) break; // nothing divides past n
}
}
long count = n / combined;
// odd number of sets -> add, even -> subtract
total += (Integer.bitCount(mask) % 2 == 1) ? count : -count;
}
return total;
}
Integer.bitCount(mask) gives the number of sets in this term. Starting the loop at mask = 1 skips the empty subset, which contributes nothing.
Practical limits
The cost is O(2k · k), so k must be small — up to about 20. That is exactly the constraint you should look for: a problem giving you at most 15 or 20 conditions and asking for a union is signalling inclusion-exclusion.
The if (combined > n) break; guard matters for more than speed. LCMs grow multiplicatively, and without an early exit the intermediate value can overflow long even though the final count is zero.
Complementary counting
Often easier than the alternating sum: count what you do not want and subtract from the total.
How many integers from 1 to N are coprime to M?
Counting them directly is awkward. Counting those sharing a factor with M is inclusion-exclusion over M’s distinct prime factors — and the complement gives the answer.
static long countCoprime(long n, long m) {
List<Long> primes = distinctPrimeFactors(m);
int k = primes.size();
long total = 0;
for (int mask = 0; mask < (1 << k); mask++) {
long product = 1;
for (int i = 0; i < k; i++) {
if ((mask & (1 << i)) != 0) product *= primes.get(i);
}
long count = n / product;
total += (Integer.bitCount(mask) % 2 == 0) ? count : -count;
}
return total;
}
Note this version starts at mask = 0 and uses the opposite sign convention, because the empty subset contributes the full count n from which the rest is subtracted. Which convention you need depends on whether you are counting the union or its complement — derive it on a tiny case rather than recalling it.
Only distinct prime factors matter. Including a repeated prime would double-count. See Number Theory Basics.
Try the complement first
Before setting up an alternating sum, ask whether the complement is easier:
- “at least one” → total minus “none”
- “not all distinct” → total minus “all distinct”
- “connected” → total minus “disconnected”
- “contains a forbidden pattern” → total minus “avoids it entirely”
Complementary counting is often a single subtraction where the direct count would be a full inclusion-exclusion.
Two dimensions
The 2D prefix-sum query is inclusion-exclusion on rectangles:
long sum = pre[r2 + 1][c2 + 1]
- pre[r1][c2 + 1]
- pre[r2 + 1][c1]
+ pre[r1][c1];
Two overlapping strips are removed, and their shared corner — subtracted twice — is added back. The same reasoning gives the area of a union of rectangles, and the sign pattern is identical.
Derangements
How many permutations leave no element in its original position?
Let A_i be the permutations fixing position i. You want the complement of the union of all A_i. Inclusion-exclusion collapses to a clean recurrence:
static long[] derangements(int n, long mod) {
long[] d = new long[n + 1];
d[0] = 1;
if (n >= 1) d[1] = 0;
for (int i = 2; i <= n; i++) {
d[i] = (i - 1) * (d[i - 1] + d[i - 2]) % mod;
}
return d;
}
This is worth knowing as a finished result. The alternating-sum derivation is instructive, but the recurrence is what you would actually write, and it is O(N) rather than O(N) terms of factorials and inverses.
When inclusion-exclusion applies
| Question | Approach |
|---|---|
| Divisible by any of k numbers | Alternating sum over subsets, LCM per term |
| Coprime to M | Complement over M's distinct primes |
| Area covered by k rectangles | Alternating sum of intersections |
| At least one of several properties | Total minus none |
| No element in its original place | Derangement recurrence |
| Surjective functions onto k values | Alternating sum over how many values go unused |
Common mistakes
- Wrong sign convention. Derive it on a two-set example every time.
- Including the empty subset when counting a union, or excluding it when counting a complement.
- Using the product instead of the LCM for “divisible by both”.
- Repeated prime factors in the coprime count.
- Overflow in the intermediate LCM or product. Break out as soon as it exceeds
n. - 2k with k too large. Above roughly 20 sets, a different technique is needed.
- Forgetting to normalize negative values when working under a modulus. See Modular Arithmetic.
Practice
- Count the integers from 1 to N divisible by at least one of 2, 3, or 5.
- Given k ≤ 15 numbers, count the integers from 1 to N (up to 1018) divisible by at least one of them.
- Count the integers from 1 to N coprime to M.
- Given k ≤ 10 axis-aligned rectangles, print the total area covered by at least one.
- Count the permutations of
1..Nwhere no element is in its original position, modulo 109+7.
Hints
- Three-set formula with LCMs.
- Bitmask over subsets. Break early when the LCM exceeds N to avoid overflow.
- Complement over the distinct prime factors of M.
- Alternating sum over subsets; the intersection of a set of rectangles is bounded by the maximum of the left edges and the minimum of the right edges. See Rectangle Geometry.
- The derangement recurrence.