← All Posts
Combinatorics II — Advanced· Part 1 of 16

Burnside's Lemma — Orbit Counting & Symmetry Groups

Introduction

Suppose you need to count the number of distinct necklaces you can make with n beads and k colours, where two necklaces are the same if one can be rotated into the other. Naively iterating over all kn colourings and deduplicating is far too slow for competitive-programming constraints (n up to 109). Burnside's Lemma turns this exponential brute force into a clean O(n) — or even O(√n) — summation.

Historically the result is due to Cauchy (1845) and Frobenius (1887); Burnside merely popularized it in his 1897 textbook. It is sometimes called the Cauchy–Frobenius lemma or the orbit-counting theorem. Despite the naming controversy, the competitive-programming community universally calls it "Burnside's Lemma."

When do you need Burnside? Any time a problem says "count distinct objects up to symmetry" — necklaces, bracelets, coloured grids, molecular structures, tile patterns — Burnside (or its generalization, Pólya) is the tool.

The Theorem

Definitions

Let X be a finite set (the set of all colourings) and G a finite group that acts on X (the symmetry group). For each element g ∈ G, define the fixed-point set:

Fix(g) = { x ∈ X : g · x = x }

An orbit of x ∈ X is the set { g · x : g ∈ G }. Two elements in the same orbit are "equivalent under G." The number of distinct orbits is written |X/G|.

Formal Statement

|X/G| = (1 / |G|) · Σg∈G |Fix(g)|

In words: the number of distinct objects equals the average number of colourings fixed by each group element. This is remarkable — instead of grouping colourings into orbits (hard), we simply count fixed points of each symmetry (easy) and average.

Proof Sketch (Double Counting)

Count the set S = { (g, x) ∈ G × X : g · x = x } in two ways. Summing over G gives Σg |Fix(g)|. Summing over X gives Σx |Stab(x)|, where Stab(x) is the stabiliser of x. By the orbit-stabiliser theorem, |Stab(x)| = |G| / |Orb(x)|. Grouping by orbits:

Σx |G| / |Orb(x)| = |G| · Σorbits O Σx ∈ O 1/|O| = |G| · (number of orbits).

Equating both sides and dividing by |G| yields the lemma. ■

Modular arithmetic caveat. In CP, results are often modulo a prime p. Dividing by |G| becomes multiplication by the modular inverse of |G| mod p. Make sure gcd(|G|, p) = 1 — which it always is when p is the typical 109+7 and |G| ≤ 109.

Symmetry Groups for CP

Cyclic Group Cn (Rotations Only)

The rotations of a regular n-gon form the cyclic group Cn = { r0, r1, …, rn−1 }, where ri denotes rotation by i · 360°/n. The group has order n.

For a rotation ri acting on an n-bead necklace with k colours, a colouring is fixed if and only if it is periodic with period gcd(i, n). Hence:

|Fix(ri)| = kgcd(i,n)

The full Burnside formula under cyclic rotations becomes:

|X/Cn| = (1/n) · Σi=0n−1 kgcd(i,n)

Optimisation via Divisors

Since gcd(i, n) depends only on the divisor d = gcd(i, n), we can group terms by d | n. For each divisor d of n, there are φ(n/d) values of i with gcd(i, n) = d (where φ is Euler's totient). So:

|X/Cn| = (1/n) · Σd|n φ(n/d) · kd

This reduces the summation from n terms to O(√n) terms (the number of divisors), which is crucial when n can be up to 109.

Dihedral Group Dn (Rotations + Reflections)

For bracelets (necklaces that can also be flipped), the symmetry group is Dn with |Dn| = 2n. It contains the n rotations from Cn plus n reflections. The reflection fixed-point counts differ for odd and even n:

n odd

All n reflections pass through one vertex and the midpoint of the opposite edge. Each reflection fixes k(n+1)/2 colourings.

n even

n/2 reflections pass through two opposite vertices — each fixes kn/2+1. n/2 reflections pass through two edge midpoints — each fixes kn/2.

Interactive Visualization

Below we animate Burnside's Lemma on a 4-bead necklace with 2 colours. There are 24 = 16 total colourings and 4 rotations (C4). Step through each rotation to see which colourings it fixes, then watch the final orbit count emerge.

0 1 2 3 Rotation |Fix| r⁰ (0°) — r¹ (90°) — r² (180°) — r³ (270°) — Σ|Fix| = — Orbits = —

Click Step to apply each rotation and count fixed colourings.

Worked Examples

Example 1 — Necklace with n=4 beads, k=2 colours (rotations only)

Group: C4 = { r0, r1, r2, r3 }.

|X/G| = (16 + 2 + 4 + 2) / 4 = 24 / 4 = 6 distinct necklaces.

Example 2 — n = 6 beads, k = 3 colours, rotations only

Divisors of 6: {1, 2, 3, 6}. Using the optimised formula:

|X/C6| = (6 + 18 + 27 + 729) / 6 = 780 / 6 = 130

Example 3 — Codeforces-Style Problem

Problem. You have a circular arrangement of n seats. Each seat can be painted one of k colours. Two arrangements are identical if one can be obtained from the other by rotation. Count the number of distinct arrangements modulo 109+7. Constraints: 1 ≤ n, k ≤ 109.

This is exactly the necklace-counting formula under Cn. Since n can be 109, we must use the divisor-based optimisation. Enumerate divisors d of n in O(√n), compute φ(n/d) and kd mod p for each, sum up, and multiply by the modular inverse of n.

C++ Implementation

Core Utilities

#include <bits/stdc++.h>
using namespace std;

const long long MOD = 1e9 + 7;

long long power(long long base, long long exp, long long mod) {
    long long result = 1;
    base %= mod;
    while (exp > 0) {
        if (exp & 1) result = result * base % mod;
        base = base * base % mod;
        exp >>= 1;
    }
    return result;
}

long long modinv(long long a, long long mod) {
    return power(a, mod - 2, mod);  // Fermat's little theorem
}

long long euler_phi(long long n) {
    long long result = n;
    for (long long p = 2; p * p <= n; ++p) {
        if (n % p == 0) {
            while (n % p == 0) n /= p;
            result -= result / p;
        }
    }
    if (n > 1) result -= result / n;
    return result;
}

Necklace Counting (Rotations — Cn)

long long burnside_necklace(long long n, long long k) {
    // |X/C_n| = (1/n) * sum over d|n of phi(n/d) * k^d
    long long ans = 0;
    for (long long d = 1; d * d <= n; ++d) {
        if (n % d != 0) continue;
        // divisor pair: d and n/d
        ans = (ans + euler_phi(n / d) % MOD * power(k, d, MOD)) % MOD;
        if (d != n / d) {
            ans = (ans + euler_phi(d) % MOD * power(k, n / d, MOD)) % MOD;
        }
    }
    ans = ans % MOD * modinv(n % MOD, MOD) % MOD;
    return ans;
}

Bracelet Counting (Rotations + Reflections — Dn)

long long burnside_bracelet(long long n, long long k) {
    // Start with the rotation sum (C_n contribution)
    long long rot = 0;
    for (long long d = 1; d * d <= n; ++d) {
        if (n % d != 0) continue;
        rot = (rot + euler_phi(n / d) % MOD * power(k, d, MOD)) % MOD;
        if (d != n / d)
            rot = (rot + euler_phi(d) % MOD * power(k, n / d, MOD)) % MOD;
    }

    // Reflection contribution
    long long ref = 0;
    if (n % 2 == 1) {
        // all n reflections: each fixes k^((n+1)/2)
        ref = (long long)(n % MOD) * power(k, (n + 1) / 2, MOD) % MOD;
    } else {
        // n/2 axis-through-vertices reflections: k^(n/2+1) each
        // n/2 axis-through-edges reflections:    k^(n/2)   each
        long long half = n / 2 % MOD;
        ref = half * power(k, n / 2 + 1, MOD) % MOD;
        ref = (ref + half * power(k, n / 2, MOD)) % MOD;
    }

    long long total = (rot + ref) % MOD;
    total = total * modinv(2 * n % MOD, MOD) % MOD;
    return total;
}

Main — Reading Input and Solving

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    long long n, k;
    cin >> n >> k;

    cout << burnside_necklace(n, k) << "\n";
    // For bracelets: cout << burnside_bracelet(n, k) << "\n";
    return 0;
}
Complexity. Enumerating divisors of n is O(√n). For each divisor we compute φ in O(√(n/d)) and kd in O(log d). Total: O(√n · √n) = O(n) in the worst case, but typically much faster because divisor counts are small. For n = 109 the number of divisors is at most ~1344, so the runtime is negligible.

Common Patterns & Pitfalls

Burnside vs Pólya

Burnside's Lemma

Counts the number of distinct objects. You must compute |Fix(g)| for each group element yourself.

Pólya Enumeration

Gives a generating function (cycle index) that can also count by weight. Subsumes Burnside and handles "how many necklaces have exactly 3 red beads."

Use Burnside when you only need the total count. Switch to Pólya when the problem asks for counts filtered by colour frequency or a generating-function approach.

Pitfall 1 — Forgetting the Modular Inverse

The formula divides by |G|. Under modular arithmetic, you must use modinv(|G|, MOD). Integer division will produce wrong answers.

Pitfall 2 — Incorrect Euler Phi

A common mistake is implementing φ with result -= result / p but forgetting to fully divide out p from n first. The standard sieve-style implementation above is correct; study it carefully.

Pitfall 3 — Bracelet vs Necklace

Problems that say "necklace" sometimes mean rotations only, sometimes rotations and reflections (bracelet). Read the statement carefully. If flipping is allowed, the group is Dn, not Cn, and the answer is smaller.

Pitfall 4 — Overcounting with Non-Standard Groups

Some problems define custom equivalences (e.g., two colourings of a cube are the same under any rotation of the cube). You must correctly enumerate the symmetry group. For a cube the rotation group has 24 elements; for a regular tetrahedron, 12.

Edge case: When n = 1, C1 has only the identity, and the answer is simply k. Make sure your divisor loop handles d = n correctly.

Practice Problems

  1. Codeforces 474F — Columns — Burnside on grid colourings with cyclic shifts.
  2. CSES — Counting Necklaces — Classic necklace counting under rotation (Cn).
  3. CSES — Counting Grids — 2D grid colourings under the 4-rotation group.
  4. SPOJ — TICTACTO — Count distinct tic-tac-toe boards under the dihedral group of the square.
  5. AtCoder ABC198 F — Cube — Burnside on 3D rotations of a cube.
  6. Codeforces Gym 100162 — Assorted Burnside/Pólya problems for practice.