PrevNext
Has Not Appeared
 0/19

Prefix Sums of Multiplicative Functions

Authors: Tianqin Meng, Benjamin Qi

This module delves into the topic of multiplicative functions and their properties.

Edit This Page

Prerequisite Skills

Definition of multiplicative functions

  1. If a function f(n) maps positive integers to complex numbers (f: ℤ⁺ → ℂ), it's an arithmetic function.
  2. If f(n) is an arithmetic function, f(1) = 1 and f(p⋅q) = f(p)⋅f(q) for any coprime positive integers p,q, it's a multiplicative function.
  3. Further, if f(n) is multiplicative and f(p⋅q) = f(p)⋅f(q) for any positive integers p,q, it's a completely multiplicative function.

Properties and Examples of Multiplicative Functions

  1. Common multiplicative functions are

    • Divisor function: σk(n)=dndk\sigma_k(n) = \sum_{d|n} d^k, representing the sum of the kkth powers of divisors of nn. Note that σk(n)\sigma_k(n) and σk(n)σ^k(n) are different.
    • Divisor count function: τ(n)=σ0(n)=dn1\tau(n) = \sigma_0(n) = \sum_{d|n} 1, representing the count of divisors of nn, also denoted as d(n)d(n).
    • Divisor sum function: σ(n)=σ1(n)=dnd\sigma(n) = \sigma_1(n) = \sum_{d|n} d, representing the sum of divisors of nn.
    • Euler's totient function: φ(n)=i=1n[(n,i)=1]1\varphi(n) = \sum_{i=1}^n [(n,i)=1] \cdot 1, representing the count of positive integers less than or equal to nn and coprime to nn. Additionally, i=1n[(n,i)=1]i=\sum_{i=1}^n [(n,i)=1] \cdot i = nφ(n)+[n=1]2\frac{n\varphi(n) + [n=1]}{2}, φ(n)\varphi(n) is even.
    • Möbius function: μ(n)\mu(n), serving as the multiplicative inverse of the identity function in Dirichlet convolution, μ(1)=1\mu(1) = 1, for a square-free number n=i=1tpin = \prod_{i=1}^t p_i, μ(n)=(1)t\mu(n) = (-1)^t, and for a number with square factors, μ(n)=0\mu(n) = 0.
    • Unit function: e(n)=[n=1]e(n) = [n=1], serving as the identity element in Dirichlet convolution, completely multiplicative.
    • Constant function: I(n)=1I(n) = 1, completely multiplicative.
    • Identity function: id(n)=nid(n) = n, completely multiplicative.
    • Power function: idk(n)=nkid^k(n) = n^k, completely multiplicative.
  2. The two classic formulas regarding the Möbius function and the Euler function are:

    • [n=1]=dnμ(d)[n=1] = \sum_{d|n} \mu(d), Interpreting μ(d)\mu(d) as the coefficients of the inclusion-exclusion principle proves it.
    • n=dnφ(d)n = \sum_{d|n} \varphi(d). To prove it, we can count the number of occurrences of 1n(1in\frac{1}{n}(1 \leq i \leq n) in its simplest fraction form.
  3. If f(n)f(n) is a multiplicative function, then for a positive integer n=i=1kpikin = \prod_{i=1}^{k} p_i^{k_i}, we have f(n)=i=1kf(piki)f(n) = \prod_{i=1}^{k} f(p_i^{k_i}); If f(n)f(n) is a completely multiplicative function, then for a positive integer n=i=1kpikin = \prod_{i=1}^{k} p_i^{k_i}, we have: f(n)=i=1kf(pi)kif(n) = \prod_{i=1}^{k} f(p_i)^{k_i}

Dirichlet Convolution and Möbius Inversion

  1. The Dirichlet convolution of number-theoretic functions ff and gg is defined as (fg)(n)=dnf(d)g(nd)(f*g)(n) = \sum_{d|n} f(d) \cdot g(\frac{n}{d}). Dirichlet convolution satisfies commutativity, associativity, and distributivity with respect to addition. There exists an identity function e(n)=[n=1]e(n) = [n=1] such that fe=f=eff*e = f = e*f。If ff and gg are multiplicative functions, then fgf*g is also multiplicative.

  2. A common technique with Dirichlet convolution involves dealing with the convolution of a multiplicative function ff and the identity function II. For example, if n=i=1tpikin = \prod_{i=1}^{t} p_i^{k_i} and g(n)=dnf(d)g(n) = \sum_{d|n} f(d),then:g(n)=i=1tj=0kif(pij)g(n) = \prod_{i=1}^{t} \sum_{j=0}^{k_i} f(p_i^j)

  3. Möbius inversion is also a discussion regarding g(n)=dnf(d)g(n) = \sum_{d|n} f(d) , but it does not require ff to be multiplicative and is applicable in cases where g(n)g(n) is known and f(n)f(n) is to be determined. Since Iμ=eI*\mu = egμ=fIμ=fe=fg*\mu = f*I*\mu = f*e = f,and f(n)=dng(d)μ(nd)f(n) = \sum_{d|n} g(d) \cdot \mu\left(\frac{n}{d}\right). Similarly, g(n)=ndf(d)f(n)=ndg(d)μ(dn)g(n) = \sum_{n|d} f(d) \Rightarrow f(n) = \sum_{n|d} g(d) \cdot \mu\left(\frac{d}{n}\right),Binomial inversion is also a similar technique. An example illustrates the relationship between the Euler function and the Möbius function: since dnφ(d)=n\sum_{d|n} \varphi(d) = n,then φ(n)=dnμ(d)nd\varphi(n) = \sum_{d|n} \mu(d) \cdot \frac{n}{d},which implies φ(n)n=dnμ(d)d\frac{\varphi(n)}{n} = \sum_{d|n} \frac{\mu(d)}{d}

Focus problem # 1 https://judge.yosupo.jp/problem/enumerate_primes

Let the prime numbers be p0<p1<p2<p_0 < p_1 < p_2 < \cdots (i.e. p0=2,p1=3,p2=5,p_0 = 2, p_1 = 3, p_2 = 5, and so on).

You are given integers N,A,N, A, and BB. Find π(N)\pi(N) (the number of primes no greater than NN), and print ipAi+B\sum_{i} p_{Ai+B} for nonnegative integers ii with ipAi+BN\sum_{i} p_{Ai+B} \leq N.

Constraints

  • 1N5×1081 \leq N \leq 5 \times 10^8
  • 0A<BN0 \leq A < B \leq N
  • 0B<AN0 \leq B < A \leq N
  • 0X1060 \leq X \leq 10^6 where X=#{iZ0ipAi+BN}X = \# \{ i \in \mathbb{Z}_{\geq 0} \mid \sum_{i} p_{Ai+B} \leq N \}

Approach:

First a review on linear sieve, this will be used in both focus problem 1 and 3:

C++

void get_prime(int n) {
for (int i = 2; i <= n; i++) {
if (!st[i]) primes[++cnt] = i;
for (int j = 1; primes[j] <= n / i; j++) {
st[i * primes[j]] = true;
if (i % primes[j] == 0) break;
}
}
}

Focus problem 1 requires finding the count of prime numbers not exceeding a given integer N and then calculating the sum of primes based on specific conditions. The provided solution employs the Sieve of Eratosthenes algorithm, which efficiently finds prime numbers up to a given limit. Here's how the solution works:

  1. Sieve of Eratosthenes: The algorithm efficiently identifies prime numbers up to a given limit by marking multiples of primes as composite.
  2. Input and Initialization: The program reads input values N, A, and B, and initializes arrays to store prime numbers (p) and their count (pc).
  3. Counting and Summing Primes: After sieving for prime numbers up to N, the program calculates the count of terms (x) in the sum ipAi+B\sum_{i} p_{Ai+B} that do not exceed N. It does this by considering the quotient of the total count of prime numbers divided by A, adjusting for the remainder.
  4. Output: The program prints the count of prime numbers (pc) and the count of terms in the sum (x). Then, it outputs the prime numbers contributing to the sum, starting from index B and skipping A elements each time.

C++

#include <bits/stdc++.h>
using namespace std;
constexpr int N(5e8), M(3.2e7);
int p[M], pc;
void sieve(int n) {
if (n < 2) return;
vector<bool> np(n + 1);
p[pc++] = 2;
int i;
for (i = 3; 1ll * i * i <= n; i += 2) {

Focus problem # 2

Find the sum of divisors of the first nn positive integers, i.e., i=1nσ(i)\sum_{i=1}^n \sigma(i), where n1012n \leq 10^{12}.

Approach:

It's not feasible to compute directly, but we can derive it as follows:

i=1nσ(i)=i=1nj=1n[ji]j=i=1nij=1n[ij]=i=1nini\sum_{i=1}^{n}\sigma(i)=\sum_{i=1}^{n}\sum_{j=1}^{n}[j|i]\cdot j=\sum_{i=1}^{n}i\cdot\sum_{j=1}^{n}[i|j]=\sum_{i=1}^{n}i\cdot\left\lfloor\frac{n}{i}\right\rfloor

When ini \leq \sqrt{n}, there are only O(n)O(\sqrt{n}) distinct values for ni\left\lfloor\frac{n}{i}\right\rfloor. Similarly, when i>ni > \sqrt{n}, ni<n\left\lfloor\frac{n}{i}\right\rfloor < n has only O(n)O(\sqrt{n}) distinct values. For a fixed ni\left\lfloor\frac{n}{i}\right\rfloor, the values of ii form a contiguous interval, which is [nni+1+1,nni]\left[\left\lfloor\frac{n}{\left\lfloor\frac{n}{i}\right\rfloor+1}\right\rfloor+1,\left\lfloor\frac{n}{\left\lfloor\frac{n}{i}\right\rfloor}\right\rfloor\right]. Therefore, the calculation can be done in O(n)O(\sqrt{n}) time.

Similarly, the sum of the number of divisors for the first nn positive integers can be calculated in the same manner. I leave this as an exercise for the reader.

Another thing to note is that i=1nnii=i=1nni(ni+1)2\sum_{i=1}^{n}\left\lfloor\frac{n}{i}\right\rfloor\cdot i=\sum_{i=1}^{n}\left\lfloor\frac{n}{i}\right\rfloor\cdot\frac{(\left\lfloor\frac{n}{i}\right\rfloor+1)}{2}. This is also a common representation form.

C++

#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
long long n, i, a, b;
long long sum;
int main() {
scanf("%lld", &n);

Focus problem # 3

Now let's increase the difficulty a bit. We want to find the sum of Euler's totient function for the first nn positive integers, i.e., i=1nφ(i)\sum_{i=1}^{n} \varphi(i), where n1011n \leq 10^{11}.

Approach:

Currently, the formulas related to Euler's totient function mentioned in this article are limited. Can we use them to simplify the problem? The answer is yes, and now we'll utilize the formula dnφ(d)=n\sum_{d|n}\varphi(d)=n to simplify the expression.

This formula can also be seen as φ(n)=ndn,d<nφ(d)\varphi(n)=n-\sum_{d|n, d<n}\varphi(d). Let's denote ϕ(n)=i=1nφ(i)\phi(n)=\sum_{i=1}^n \varphi(i), then we have:

ϕ(n)=i=1nφ(i)=i=1nidi,d<iφ(d)=n(n+1)2i=2ndi,d<iφ(d)=n(n+1)2i=2nd=1n(id)φ(d)\phi(n)=∑_{i=1}^n\varphi(i)=∑_{i=1}^n i−∑_{d|i,d<i}\varphi(d)=\frac{n\cdot(n+1)}{2}−∑_{i=2}^n\sum_{d|i,d<i}\varphi(d)=\frac{n\cdot(n+1)}{2}−\sum_{i=2}^{n}\sum_{d=1}^{\left\lfloor\frac{n}{\left(\frac{i}{d}\right)}\right\rfloor}\varphi(d)
n(n+1)2i=2nd=1niϕ(d)=n(n+1)2i=2nϕ(ni)n \cdot \frac{(n+1)}{2} - \sum_{i=2}^{n} \sum_{d=1}^{\lfloor \frac{n}{i} \rfloor} \phi(d) = n \cdot \frac{(n+1)}{2} - \sum_{i=2}^{n} \phi(\lfloor \frac{n}{i} \rfloor)

So as long as you calculate the values of ϕ(ni\phi(\lfloor \frac{n}{i} \rfloor for O(n)O(\sqrt{n}) times, you can compute ϕ(n)\phi(n). What about the complexity of such an operation?

Suppose the complexity of calculating ϕ(n)\phi(n) is T(n)T(n), then we have T(n)=O(n)+i=1nT(i)+T(n/i)T(n) = O(\sqrt{n}) + \sum_{i=1}^{\sqrt{n}} T(i) + T(n/i). Here, we only expand one layer because deeper complexities are higher-order terms. So, we have T(n)=i=1nO(i)+O(ni)=O(n3/4)T(n) = \sum_{i=1}^{\sqrt{n}} O(\sqrt{i}) + O(\sqrt{\frac{n}{i}}) = O(n^{3/4}).

Since ϕ(n)\phi(n) is a prefix sum of a multiplicative function, the sieve method can preprocess a portion. Assuming the preprocessing includes the first kk positive integers' ϕ(n)\phi(n) where knk \geq \sqrt{n}, the complexity becomes T(n)=i=1kni=O(nk)T(n) = \sum_{i=1}^{k} {\sqrt{\frac{n}{i}}} = O({\frac{n}{\sqrt{k}}}). When k=O(n2/3)k = O(n^{2/3}), we can achieve a good complexity of T(n)=O(n2/3)T(n) = O(n^{2/3}).

How did we come up with the place where we utilized φ(n)=ndn,d<nφ(d)\varphi(n) = n-\sum_{d|n,d<n} \varphi(d)? Let's take a look at this:

n(n+1)2=i=1ni=i=1nd[di]φ(d)=i=2nd=1n(id)φ(d)=i=1nϕ(ni)\frac{n \cdot (n+1)}{2} = \sum_{i=1}^{n} i = \sum_{i=1}^{n} \sum_{d} [d|i]\varphi(d) = \sum_{i=2}^{n} \sum_{d=1}^{\left\lfloor \frac{n}{\left(\frac{i}{d}\right)} \right\rfloor} \varphi(d) = \sum_{i=1}^{n} \phi(\left\lfloor \frac{n}{i} \right\rfloor)

If we can construct a function through Dirichlet convolution that computes prefix sums more efficiently and if another function suitable for convolution is also easy to calculate, we can simplify the calculation process. For example, in the above problem, we used the property of φI=id\varphi * I = id. But remember, not all problems of this type can be easily solved by just pairing with an identity function II. Sometimes, a more careful observation is needed.

C++

#include <cstring>
#include <iostream>
using namespace std;
typedef long long ll;
const int N = 1e6 + 10;
int primes[N];
ll phi[N];
bool st[N];
int cnt;

More information below left over by Benjamin Qi

https://codeforces.com/blog/entry/54150

Linear Time Sieve

https://judge.yosupo.jp/problem/enumerate_primes

Counting Primes

https://judge.yosupo.jp/problem/counting_primes

Totient Function

https://judge.yosupo.jp/problem/sum_of_totient_function

template <int SZ> struct Sieve {
vi pr;
int sp[SZ], phi[SZ]; // smallest prime that divides
Sieve() { // above is faster
memset(sp, 0, sizeof sp);
phi[1] = 1;
FOR(i, 2, SZ) {
if (sp[i] == 0) {
sp[i] = i, pr.pb(i);
phi[i] = i - 1;

(project euler)

(topcoder problem)

Problems

Here are some practice problems for everyone to understand the methods mentioned above. Such problems are relatively few, so if you have other sources of problems, please feel free to share.

Module Progress:

Join the USACO Forum!

Stuck on a problem, or don't understand a module? Join the USACO Forum and get help from other competitive programmers!

PrevNext