Posts

Number Theory #2-ex: Möbius Techniques

On this page

(Continues from Number Theory #2)

0.1 Basic Identities

$$\bullet\;[n=1]=\sum_{d\mid n}\mu(d)$$

$$\bullet\;n=\sum_{d\mid n}\varphi(d)\;\implies\;\varphi(n)=\sum_{d\mid n}\mu(d)\cdot\frac{n}{d}$$

$$\bullet\;\sigma(n)=\sum_{d\mid n}d$$

Indicator / sieve identities

  • Coprimality indicator: $\displaystyle[\gcd(x,n)=1]=\sum_{d\mid\gcd(x,n)}\mu(d)$
  • Congruence indicator: $[x\equiv y\pmod{d}]=[d\mid(x-y)]$

Classical divisor sums

  • $\displaystyle\sum_{d\mid n}\varphi(d)=n$
  • $\displaystyle\sum_{d\mid n}\mu(d)=[n=1]$
  • $\displaystyle\sum_{d\mid n}\tau(d)=\sum_{d\mid n}\tau(n/d)\quad(\tau=1*1,\ \tau\text{ is the divisor-count function})$
  • $\sigma=\mathrm{id}*\mathbf{1},\quad\tau=\mathbf{1}*\mathbf{1},\quad\varphi=\mu*\mathrm{id}$

GCD variants

  • $\displaystyle\gcd(a,b)=\sum_{d\mid\gcd(a,b)}\varphi(d)$
  • $\displaystyle\sum_{d\mid n}\mu(d)\Bigl\lfloor\frac{m}{d}\Bigr\rfloor$ = “count of $x\in[1,m]$ coprime to $n$” (inclusion-exclusion over prime factors of $n$)
  • $\displaystyle d(xy)=\sum_{a\mid x}\sum_{b\mid y}[\gcd(a,b)=1]$

GCD-layered substitution (very common)

$$\sum_{k=1}^{n}f\!\bigl(\gcd(k,n)\bigr)=\sum_{d\mid n}f(d)\,\varphi\!\left(\frac{n}{d}\right)$$

(Group $k$ by $\gcd(k,n)=d$.)


1 Trick 1 — Loop Shortening via Divisibility

When iterating $i=1,\ldots,n$, if the expression is non-zero only when $k\mid i$, shorten the loop:

$$\sum_{i=1}^{n}[k\mid i]=\sum_{i=1}^{\lfloor n/k\rfloor}1=\Bigl\lfloor\frac{n}{k}\Bigr\rfloor$$

Example: $\displaystyle\sum_{i=1}^n\sum_{j=1}^m[\gcd(i,j)=k]$

Substitute $i=i'k$, $j=j'k$; the condition $\gcd(i,j)=k$ becomes $\gcd(i',j')=1$:

$$\sum_{i=1}^n\sum_{j=1}^m[\gcd(i,j)=k]=\sum_{i'=1}^{\lfloor n/k\rfloor}\sum_{j'=1}^{\lfloor m/k\rfloor}[\gcd(i',j')=1]$$

Key point: non-zero entries appear only every $k$ steps in both loops, so the range shrinks by factor $k$.


2 Trick 2 — Convert GCD-Divisors to Individual Divisors

$$[\gcd(x,y)=1]=\sum_{d\mid\gcd(x,y)}\mu(d)=\sum_{\substack{d\mid x\\d\mid y}}\mu(d)=\sum_{d=1}^{n}\mu(d)\cdot[d\mid x]\cdot[d\mid y]$$

Core idea: $\gcd(i,j)$ varies with $i,j$ so its divisors are hard to enumerate directly. Use $d\mid\gcd(i,j)\iff d\mid i\text{ and }d\mid j$ to decouple the two indices.

Example: $\displaystyle\sum_{i=1}^n\sum_{j=1}^m[\gcd(i,j)=1]$

$$\begin{align} \sum_{i=1}^n\sum_{j=1}^m[\gcd(i,j)=1] &=\sum_{i=1}^n\sum_{j=1}^m\sum_{d\mid\gcd(i,j)}\mu(d)\\ &=\sum_{d=1}^{\min(n,m)}\mu(d)\sum_{i=1}^n[d\mid i]\sum_{j=1}^m[d\mid j]\\ &=\sum_{d=1}^{\min(n,m)}\mu(d)\Bigl\lfloor\frac{n}{d}\Bigr\rfloor\Bigl\lfloor\frac{m}{d}\Bigr\rfloor \end{align}$$

The last sum is evaluated in $O\!\left(\sqrt{\min(n,m)}\right)$ via divisibility blocking.

Example 1: Luogu P3455 [POI2007] ZAP-Queries

$$\text{Compute }\sum_{i=1}^n\sum_{j=1}^m[\gcd(i,j)=k],\quad 1\leq T,n,m,k\leq5\times10^4$$
  • Trick 1: reduce to $\sum_{i=1}^{\lfloor n/k\rfloor}\sum_{j=1}^{\lfloor m/k\rfloor}[\gcd(i,j)=1]$.
  • Trick 2: $=\displaystyle\sum_{d=1}^{\min(\lfloor n/k\rfloor,\lfloor m/k\rfloor)}\mu(d)\Bigl\lfloor\frac{\lfloor n/k\rfloor}{d}\Bigr\rfloor\Bigl\lfloor\frac{\lfloor m/k\rfloor}{d}\Bigr\rfloor$.

Supplementary identity: $\displaystyle\Bigl\lfloor\frac{\lfloor n/k\rfloor}{d}\Bigr\rfloor=\Bigl\lfloor\frac{n}{kd}\Bigr\rfloor$. The two forms are equivalent; the right-hand form is cleaner in derivations, the left-hand form is more natural in code.

int main(){
    long long t;
    read(t);
    get_mu(50000);
    while(t--){
        static long long a, b, d;
        read(a); read(b); read(d);
        static long long max_rep, ans;
        max_rep = min(a, b); ans = 0;
        for(long long l=1, r; l<=max_rep; l=r+1){
            r = min(a/(a/l), b/(b/l));
            ans += (a/(l*d)) * (b/(l*d)) * (sum[r] - sum[l-1]);
        }
        printf("%lld\n", ans);
    }
    return 0;
}

Example 2: Luogu P2522 [HAOI2011] Problem b

$$\text{Compute }\sum_{i=x}^n\sum_{j=y}^m[\gcd(i,j)=k],\quad 1\leq T,x,y,n,m,k\leq5\times10^4$$

Reduce to four $(1,\cdot)$-based queries via 2D prefix-sum inclusion-exclusion:

$$\sum_{i=x}^n\sum_{j=y}^m[\gcd(i,j)=k] =\sum_{1..n;1..m}-\sum_{1..x-1;1..m}-\sum_{1..n;1..y-1}+\sum_{1..x-1;1..y-1}$$

3 Trick 3 — Reduce a General $f(\gcd)$ Sum to $[\gcd=1]$ Form

Replace the inner expression $f(\gcd(i,j))$ by $f(d)\cdot[\gcd(i',j')=1]$ by factoring out $d=\gcd(i,j)$.

The most common Möbius pattern: $\displaystyle\sum_{i=1}^n\sum_{j=1}^mf(\gcd(i,j))$.

Set $d=\gcd(i,j)$, $i=i'd$, $j=j'd$; then $\gcd(i',j')=1$ (otherwise $d$ is not maximal).

Add an outer loop over $d$ and shrink the inner ranges (Trick 1):

$$\begin{align} \sum_{i=1}^n\sum_{j=1}^mf(\gcd(i,j)) &=\sum_{d=1}^{\min(n,m)}\sum_{i'=1}^{\lfloor n/d\rfloor}\sum_{j'=1}^{\lfloor m/d\rfloor}f(\gcd(i'd,j'd))\cdot[\gcd(i',j')=1]\\ &=\sum_{d=1}^{n}\sum_{i=1}^{\lfloor n/d\rfloor}\sum_{j=1}^{\lfloor m/d\rfloor}f(d)\cdot[\gcd(i,j)=1] \end{align}$$

4 Trick 4 — Substitute $T=dk$ to Identify a Dirichlet Convolution

When outer loop is $d$ and inner variable is $k$, and only their product $T=dk$ appears in floor expressions, swap to outer loop over $T$ and enumerate divisors $d\mid T$.

Starting from Trick 3:

$$S=\sum_{d=1}^n f(d)\sum_{i=1}^{\lfloor n/d\rfloor}\sum_{j=1}^{\lfloor m/d\rfloor}[\gcd(i,j)=1]$$

Step 1. Expand $[\gcd(i,j)=1]$ with Möbius, swap summation order:

$$S=\sum_{d=1}^n f(d)\sum_{k=1}^{\min(\lfloor n/d\rfloor,\lfloor m/d\rfloor)}\mu(k) \sum_{i=1}^{\lfloor n/d\rfloor}[k\mid i]\;\sum_{j=1}^{\lfloor m/d\rfloor}[k\mid j]$$

Step 2. Replace divisibility counts:

$$\sum_{i=1}^{\lfloor n/d\rfloor}[k\mid i]=\Bigl\lfloor\frac{n}{dk}\Bigr\rfloor,\qquad \sum_{j=1}^{\lfloor m/d\rfloor}[k\mid j]=\Bigl\lfloor\frac{m}{dk}\Bigr\rfloor$$$$S=\sum_{d=1}^n f(d)\sum_{k=1}^{\min(\lfloor n/d\rfloor,\lfloor m/d\rfloor)}\mu(k)\Bigl\lfloor\frac{n}{dk}\Bigr\rfloor\Bigl\lfloor\frac{m}{dk}\Bigr\rfloor$$

Step 3. Set $T=dk$. For fixed $T$, all pairs $(d,k)$ with $dk=T$ correspond to divisors $d\mid T$ with $k=T/d$. Since $dk\leq\min(n,m)$, we have $T\leq\min(n,m)$:

$$S=\sum_{T=1}^{\min(n,m)}\Bigl\lfloor\frac{n}{T}\Bigr\rfloor\Bigl\lfloor\frac{m}{T}\Bigr\rfloor\sum_{d\mid T}f(d)\,\mu\!\left(\frac{T}{d}\right)$$

Step 4. Recognise the Dirichlet convolution $g=f*\mu$:

$$g(T)=\sum_{d\mid T}f(d)\,\mu\!\left(\frac{T}{d}\right)$$$$\boxed{S=\sum_{T=1}^{\min(n,m)}g(T)\Bigl\lfloor\frac{n}{T}\Bigr\rfloor\Bigl\lfloor\frac{m}{T}\Bigr\rfloor}$$

General Formula 1. Combining Tricks 3 and 4 (assuming $n\leq m$):

$$\sum_{i=1}^n\sum_{j=1}^m f(\gcd(i,j))=\sum_{T=1}^{\min(n,m)}g(T)\Bigl\lfloor\frac{n}{T}\Bigr\rfloor\Bigl\lfloor\frac{m}{T}\Bigr\rfloor,\quad g=f*\mu$$

Limitation: the inner expression must depend only on $\gcd(i,j)$ (a univariate function). This formula does not generalise to expressions involving $i$ or $j$ independently.

4.1 Example: ZAP-Queries via General Formula 1

With $f(x)=[x=k]$:

$$g(T)=\sum_{d\mid T}[d=k]\,\mu\!\left(\frac{T}{d}\right)=[k\mid T]\,\mu\!\left(\frac{T}{k}\right)$$

Apply Trick 1 (set $T=ik$):

$$\sum_{i=1}^{\min(\lfloor n/k\rfloor,\lfloor m/k\rfloor)}\mu(i)\Bigl\lfloor\frac{n}{ik}\Bigr\rfloor\Bigl\lfloor\frac{m}{ik}\Bigr\rfloor$$

Evaluate with divisibility blocking.


5 Trick 5 — Divisor Symmetry: $d\leftrightarrow n/d$

When $d$ runs over all divisors of $n$, $d$ and $n/d$ are in bijection.

Example:

$$\frac{1}{2}\sum_{d\mid n}\frac{n^2}{d}\,\varphi\!\left(\frac{n}{d}\right)+\frac{n}{2} =\frac{1}{2}\sum_{d\mid n}n\cdot d\,\varphi(d)+\frac{n}{2}$$

(Replace $d\to n/d$ throughout the divisor sum.)


6 Trick 6 — Diagonal Symmetry: Upper Triangle vs Full Matrix

When $f(i,j)=f(j,i)$, convert between the full double sum and the upper-triangle sum.

6.1 Upper-triangle and lower-triangle

$$\sum_{i=1}^n\sum_{j=i}^n f(i,j)=\sum_{j=1}^n\sum_{i=1}^j f(i,j)$$

Both sides sum the upper-triangle region (including the diagonal); only the summation order differs.

6.2 Upper-triangle sum and full-matrix sum

$$\sum_{i=1}^n\sum_{j=i}^n f(i,j) =\frac{\displaystyle\sum_{i=1}^n\sum_{j=1}^n f(i,j)+\sum_{i=1}^n f(i,i)}{2}$$

“Upper triangle including diagonal” = (full matrix + diagonal) / 2.

Equivalently:

$$\sum_{i=1}^n\sum_{j=1}^n f(i,j)=2\sum_{i=1}^n\sum_{j=i}^n f(i,j)-\sum_{i=1}^n f(i,i)$$

7 Trick 7 — Value-Domain Möbius with $\mathrm{cnt}[\,]$

Overview: standard Möbius problems operate on $1,2,\ldots,n$. When the input is an array $a[1\cdots n]$ and summation involves number-theoretic functions of array values, introduce:

  • $w[y]$ = number of times value $y$ appears in $a[\cdot]$
  • $\mathrm{cnt}[d]$ = number of elements in $a[\cdot]$ divisible by $d$

Example. Given $a[1\cdots n]$ with $1\leq a_i\leq n$, compute:

$$\sum_{i=1}^n\sum_{j=1}^n\bigl(\gcd(a[i],a[j])+[\gcd(a[i],a[j])\neq1]\bigr)$$

Split into two parts:

$$\underbrace{\sum_{i,j}\gcd(a[i],a[j])}_{P_1}+\underbrace{\sum_{i,j}[\gcd(a[i],a[j])\neq1]}_{P_2}$$

Computing $P_2$ (non-coprime pairs):

Expand $[\gcd=1]=\sum_{d\mid\gcd}\mu(d)$, decouple with Trick 2:

$$\sum_{i,j}[\gcd(a[i],a[j])=1]=\sum_{d=1}^V\mu(d)\Bigl(\sum_i[d\mid a[i]]\Bigr)^2=\sum_{d=1}^V\mu(d)\,\mathrm{cnt}^2(d)$$$$P_2=n^2-\sum_{d=1}^V\mu(d)\,\mathrm{cnt}^2(d)$$

Computing $P_1$ (sum of GCDs):

Use Euler inversion $\mathrm{id}=\varphi*\mathbf{1}$, i.e.\ $\gcd(a,b)=\sum_{d\mid\gcd(a,b)}\varphi(d)$, then Trick 2:

$$P_1=\sum_{i,j}\gcd(a[i],a[j])=\sum_{d=1}^V\varphi(d)\,\mathrm{cnt}^2(d)$$

Final answer:

$$\text{Answer}=n^2+\sum_{d=1}^V\bigl(\varphi(d)-\mu(d)\bigr)\,\mathrm{cnt}^2(d)$$

Computing $\mathrm{cnt}[d]$: build $w[y]$ (frequency array), then for each $d$ accumulate $w[d]+w[2d]+\cdots$ — harmonic-series cost $O(V\log V)$.

Complexity: $O(V\log V)$ overall, $V=\max\{a_i\}$.

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 100000 + 10;   // set to max(a[i]) + 5 as needed
const int P = 998244353;

int n, v;
int a[N], w[N];

bool st[N];
int primes[N], tot;
int mu[N]; ll phi[N];
ll cnt[N];
vector<int> g[N];  // g[x][0] = smallest prime factor of x

// sieve + phi + mu
void get_primes(int nmax) {
    phi[1] = 1;
    for (int i = 1; i <= nmax; i++) mu[i] = 1;
    for (int i = 2; i <= nmax; i++) {
        if (!st[i]) {
            primes[tot++] = i;
            mu[i] = -1;
            phi[i] = i - 1;
            for (int j = i + i; j <= nmax; j += i) {
                st[j] = true;
                g[j].push_back(i);
                if ((j / i) % i == 0) mu[j] = 0;
                else if (mu[j] != 0) mu[j] = -mu[j];
            }
        } else {
            int p = g[i][0];        // smallest prime factor of i
            int now = i / p;
            if (now % p == 0) phi[i] = 1LL * p * phi[now];
            else              phi[i] = 1LL * (p - 1) * phi[now];
        }
    }
}

// cnt[d] = number of elements in a[] divisible by d
void get_cnt() {
    for (int i = 1; i <= n; i++) w[a[i]]++;
    cnt[1] = n;
    for (int d = 2; d <= v; d++) {
        for (int j = d; j <= v; j += d) {
            cnt[d] += w[j];   // no modular reduction: cnt[d] <= n
        }
    }
}

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

    cin >> n;
    v = 0;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
        v = max(v, a[i]);
    }

    get_primes(v);
    get_cnt();

    ll ans = 1LL * n * n % P;
    for (int d = 1; d <= v; d++) {
        ll term = (((phi[d] - mu[d]) % P) + P) % P;
        ll cd   = cnt[d] % P;
        ans = (ans + term * cd % P * cd) % P;
    }
    cout << ans << '\n';
    return 0;
}