The two most common moves in counting problems: swap the order of summation (contribution), and count the complement.
Contribution technique
Instead of summing over every structure, sum over the atoms and count how many structures each atom appears in:
| Sum over | Atom | Count |
|---|---|---|
| all subarray sums | ||
| all subsequence sums | ||
| pairwise tree distances | edge into a subtree of size | |
| subarray minimums / maximums | as the minimum | via monotonic stack |
| over all subarrays | both of the above | subtract |
| pairwise XOR | bit with ones | |
| subarray XORs, ANDs, ORs | bit | prefix parities / last zero positions |
| max of each -subset | sorted as max | |
| number of distinct values over all subarrays | first occurrence of each value in the subarray | |
| inversions over all permutations | each pair | |
| expected value | indicator of an event | its probability (linearity) |
Reach for this when: the answer sums over exponentially or quadratically many objects; the object’s value decomposes into a sum over its parts (sum, count, XOR per bit, min/max via “who is the min”); and each part’s number of containing objects has a simple closed form (product of left/right choices, a binomial, a subtree size).
Tie-breaking for minimum/maximum contributions: use strict on one side and non-strict on the other (previous strictly smaller, next smaller-or-equal), so each subarray is counted exactly once.
Proof: the contribution counts in the table, and the tie-break
Subarray sums, atom : appears in subarray iff ; there are choices of and choices of , giving subarrays.
Subsequence sums: appears in a subsequence iff it is included; the other elements are independently in or out, giving .
Tree distances, edge splitting the tree into a side of size and : , so summing over all pairs, edge is counted once for every pair with one endpoint on each side — such pairs, by independent choice of one vertex from each side.
Pairwise XOR, bit with ones among numbers: bit of is set iff exactly one of has it set, i.e. one comes from the numbers with that bit set and the other from the without — exactly such unordered pairs (one choice from each group), each contributing to the sum.
The tie-break for subarray minimums. Every subarray has a unique minimum position only if ties are broken consistently; using strictly-smaller on one side (L[i]: nearest index with ) and smaller-or-equal on the other (R[i]: nearest index with ) ensures that among several equal minimum values in one subarray, exactly one of them — the first occurrence (leftmost) — has that subarray counted in its range, since any subarray spanning multiple copies of the minimum value is only included in the range computed from the leftmost copy (the other copies’ computed ranges, using the same asymmetric rule, exclude it on their left side). This avoids both under- and over-counting duplicate minimum values.
Tested: sumSubarrayMins checked against the brute-force double sum over all subarrays, including arrays with many duplicate (tied) values, on random small arrays.
ll sumSubarrayMins(const vector<ll>& a) {
int n = a.size(); vector<int> L(n), R(n), st;
for (int i = 0; i < n; i++) {
while (!st.empty() && a[st.back()] >= a[i]) st.pop_back();
L[i] = st.empty() ? -1 : st.back(); st.push_back(i);
}
st.clear();
for (int i = n - 1; i >= 0; i--) {
while (!st.empty() && a[st.back()] > a[i]) st.pop_back();
R[i] = st.empty() ? n : st.back(); st.push_back(i);
}
ll ans = 0;
for (int i = 0; i < n; i++) ans += a[i] * (i - L[i]) * (R[i] - i);
return ans;
}Higher-order contributions
- Squares are pairs. . Count ordered pairs of atoms that lie together. The same trick gives for a count : sum over ordered pairs of .
- -th powers via falling factorials. (Stirling numbers of the second kind), and counts -subsets of atoms, which is usually easy to sum. This is how “sum over all subsets of (size)” or "" problems are solved: over subsets of an -set equals .
- Sum over pairs of a function of . , so swap to where counts multiples of (Möbius).
- “Value at least ”. For non-negative integers, . So of maxima , and . This often turns a max into a count over thresholds (“count subsets whose max is ” = all minus subsets of values ).
- Order statistics. “Sum over subsets of the -th smallest”: sort, then element contributes .
- Per-bit decomposition. Every bitwise expression splits into independent bits. Count, for each bit, how many objects have it set, then multiply by . For sums of XORs of subarrays, keep counts of prefix parities 0/1 per bit.
- Tree contributions. For pairs the edge contribution is . For -subsets of vertices, the number of subsets whose Steiner tree uses edge is .
Complementary counting
Use it when “bad” is simpler: at least one becomes none, not all equal becomes all equal, contains a pattern becomes avoids it (automaton DP), connected becomes disconnected.
| Want | Count instead |
|---|---|
| at least one | total minus none |
| strings containing a pattern | total minus avoiding strings (KMP / Aho-Corasick automaton DP) |
| intersecting pairs of intervals | all pairs minus disjoint pairs (sort by endpoints) |
| permutations with a fixed point | |
| triangles in the complement of | (Goodman: the sum counts triangles with edges of both kinds twice) |
| binary strings with “11” | (proof below) |
Connected structures by fixing the component of vertex 1. With all graphs and connected graphs:
That’s , or via the exponential formula (power series). The same pattern counts connected bipartite graphs, strongly connected tournaments and labelled DAGs (with an inclusion-exclusion sign over the set of sources).
Probability. for independent events. For dependent overlapping events use inclusion-exclusion (Inclusion-Exclusion).
Practice anchors (CSES): Distributing Apples (direct stars-and-bars, no complement needed — the contrast is instructive), Christmas Party (derangements), Grid Paths II (obstacles via complementary counting over forbidden-cell inclusion-exclusion).
Proof: "11"-avoiding binary strings count
Let be the number of length- binary strings with no two consecutive 1s. Condition on the last character: if it’s 0, the rest is any valid string of length ( ways); if it’s 1, the second-to-last must be 0 (else “11”), and the rest is any valid string of length followed by “01” ( ways). So — the Fibonacci recurrence — with , giving (matching the standard indexing ). Subtracting from the total gives the count with “11”.
Double counting
Count the same set two ways. Classic uses:
- Handshake lemma: count (vertex, incident edge) pairs.
- : count (set, chosen element) pairs.
- : count pairs with .
- Number of triangles : orient edges from low to high degree, so every vertex has out-degree .
Proof: the double-counting identities above
: count pairs (subset , marked element ) two ways. Choosing first ( ways) then the rest of freely among the remaining elements ( ways) gives ; choosing first (size , ways) then ( ways) and summing over gives . Equal.
: count pairs with and . Fixing , the multiples of up to number ; fixing , its divisors number . Summing each way counts the same set of pairs.
Triangle count via low-to-high orientation: orient every edge from the lower-degree endpoint to the higher (break ties by label), so a vertex’s out-edges go only to vertices of degree its own. Its out-degree is bounded by : if , at most other vertices can have degree (else would exceed ), and ‘s out-neighbours are a subset of those. Every triangle, listed in this orientation, has exactly one vertex from which both its other two vertices are reached by a single out-edge each (the “source” of the triangle’s two forward edges), so enumerating, for every vertex, every pair of its out-neighbours and checking the edge between them counts every triangle exactly once, in total (each vertex contributes at most its out-degree squared, and out-degree is , summed over vertex-edge incidences).
Pitfalls
- Equal values: fix a tie-break by index.
- Modular subtraction needs
(all - bad + MOD) % MOD. - Make sure “all” and “bad” live in the same universe (ordered vs unordered, labelled vs unlabelled, empty set included or not).
- Overflow in : use
llor reduce modulo.