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 overAtomCount
all subarray sums
all subsequence sums
pairwise tree distancesedge into a subtree of size
subarray minimums / maximums as the minimum via monotonic stack
over all subarraysboth of the abovesubtract
pairwise XORbit with ones
subarray XORs, ANDs, ORsbit prefix parities / last zero positions
max of each -subsetsorted as max
number of distinct values over all subarraysfirst occurrence of each value in the subarray
inversions over all permutationseach pair
expected valueindicator of an eventits 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.

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.

WantCount instead
at least one total minus none
strings containing a patterntotal minus avoiding strings (KMP / Aho-Corasick automaton DP)
intersecting pairs of intervalsall 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).

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 .

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 ll or reduce modulo.