CSES - Divisor Analysis

Author: Andi Qu

Time Complexity: O(Nlog(max(ki)))\mathcal O(N \log(\max(k_i))).

Number of divisors

Each divisor of the number can be written as i=1Nxiαi\prod_{i = 1}^N x_i^{\alpha_i} where 0αiki0 \leq \alpha_i \leq k_i.

Since there are ki+1k_i + 1 choices for αi\alpha_i, the number of divisors is simply i=1N(ki+1)\prod_{i = 1}^N (k_i + 1).

We can calculate this by iterating through the prime factors in O(N)\mathcal O(N) time.

Sum of divisors

Let the sum of divisors when only considering the first ii prime factors be SiS_i. The answer will be SNS_N.

Si=Si1j=0kixij=Si1xiki+11xi1\begin{aligned} S_i &= S_{i - 1} \sum_{j = 0}^{k_i} x_i^j\\ &= S_{i - 1} \cdot \frac{x_i^{k_i + 1} - 1}{x_i - 1}\\ \end{aligned}

We can calculate each SiS_i using fast exponentiation and modular inverses in O(Nlog(max(ki)))\mathcal O(N \log(\max(k_i))) time.

Product of divisors

Let the product and number of divisors when only considering the first ii prime factors be PiP_i and CiC_i respectively. The answer will be PNP_N.

Pi=Pi1ki+1(xiki(ki+1)/2)Ci1\begin{aligned} P_i &= P_{i - 1}^{k_i + 1} \left(x_i^{k_i(k_i + 1)/2} \right)^{C_{i - 1}} \end{aligned}

Again, we can calculate each PiP_i using fast exponentiation in O(Nlog(max(ki)))\mathcal O(N \log(\max(k_i))) time, but there's a catch! It might be tempting to use Ci1C_{i - 1} from your previously-calculated values in part 1 of this problem, but those values will yield wrong answers.

This is because ab≢abmodp(modp)a^b \not \equiv a^{b \bmod p} \pmod{p} in general. However, by Fermat's little theorem, ababmod(p1)(modp)a^b \equiv a^{b \bmod (p - 1)} \pmod{p} for prime pp, so we can just store CiC_i modulo 109+610^9 + 6 to calculate PiP_i.

C++

#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
const ll MOD = 1e9 + 7;
ll expo(ll base, ll pow) {
ll ans = 1;
while (pow) {
if (pow & 1) ans = ans * base % MOD;

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!