Higher-Order Residues & Roots of Unity

Prerequisite knowledge: Discrete Logarithm

This article discusses higher-order residues and roots of unity in modular arithmetic, and introduces algorithms for extracting roots modulo a modulus.

Higher-Order Residues

A higher-order residue in modular arithmetic can be viewed as a question of whether it is possible to extract a higher-order root modulo a modulus. It is a generalization of a quadratic residue.

kk-th Residue

Let the integer k≥2k\geq 2, and let the integer aa be coprime to the positive integer mm. If there exists an integer xx such that

xk≡a(modm),x^k\equiv a\pmod m,

then aa is, modulo mm, a kk-th residue (kk-th residue), and xx is a root of aa modulo mm of order kk (kk-th root); otherwise, aa is, modulo mm, a kk-th nonresidue (kk-th nonresidue).

In other words, aa modulo mm has a kk-th root if and only if aa modulo mm is a kk-th residue.

Properties

As with quadratic residues, one can discuss deciding kk-th residues, their number, and the number of kk-th residue classes. As with other congruence equation problems, the Chinese remainder theorem can reduce them to the case of prime-power moduli. Depending on whether a primitive root exists, this further splits into odd prime-power moduli and powers of 22.

The odd prime-power case is relatively simple. In fact, whenever a primitive root exists, we have the following result:

Theorem

Let the integer k≥2k\geq 2, and let the integer aa be coprime to the positive integer mm. Suppose a primitive root modulo mm exists, and let gg be a primitive root modulo mm. Let d=gcd⁡(k,φ(m))d=\gcd(k,\varphi(m)) and d′=φ(m)dd'=\dfrac{\varphi(m)}{d}, where φ(m)\varphi(m) is the Euler totient function. Then:

  1. aa is, modulo mm, a kk-th residue if and only if

    ad′≡1(modm).a^{d'} \equiv 1 \pmod m.
  2. If aa is, modulo mm, a kk-th residue, then aa has, modulo mm, exactly dd distinct kk-th roots, of the form

    x≡gy0+id′(modφ(m)), 0≤y0<d′, i=0,1,⋯ ,d−1.x \equiv g^{y_0+id'}\pmod{\varphi(m)},~0\le y_0 < d',~i=0,1,\cdots,d-1.
  3. The number of residue classes modulo mm of degree kk is d′d', and all of them are

    {gdi mod m:0≤i<d′}.\{g^{di}\bmod m : 0 \le i < d'\}.
Proof

Since a⊥ma\perp m, we have x⊥mx\perp m. Since gg is a primitive root modulo mm, both xx and aa are congruent to powers of gg. Let x≡gy(modm)x\equiv g^y\pmod m; then the equation xk≡a(modm)x^k\equiv a\pmod m is equivalent to

gky≡gind⁡ga(modm).g^{ky} \equiv g^{\operatorname{ind}_g a}\pmod m.

Here, ind⁡ga\operatorname{ind}_g a is the discrete logarithm. By the properties of order and δm(g)=φ(m)\delta_m(g)=\varphi(m), this is equivalent to the congruence equation

ky≡ind⁡ga(modφ(m)).ky \equiv \operatorname{ind}_g a \pmod{\varphi(m)}.

This is a linear congruence equation in yy. Applying the analysis of its solution structure on that page, we know that the equation is solvable if and only if d∣ind⁡gad\mid\operatorname{ind}_g a, and that its general solution has the form

y=y0+id′(modφ(m)), 0≤y0<d′, i=0,1,⋯ ,d−1.y = y_0 + id' \pmod{\varphi(m)},~0\le y_0 < d',~i=0,1,\cdots,d-1.

This almost gives the entire theorem. The only point that needs additional explanation is the criterion ad′≡1(modm)a^{d'} \equiv 1 \pmod m. By Property 3 of order,

δm(a)=δm(gind⁡ga)=φ(m)gcd⁡(φ(m),ind⁡ga)=φ(m)ind⁡ga.\delta_m(a) = \delta_m(g^{\operatorname{ind}_g a}) = \dfrac{\varphi(m)}{\gcd(\varphi(m),\operatorname{ind}_g a)} = \dfrac{\varphi(m)}{\operatorname{ind}_g a}.

We already know that the equation is solvable if and only if d∣ind⁡gad\mid \operatorname{ind}_g a, equivalently δm(a)∣d′\delta_m(a)\mid d'. By Property 2 of order, this is equivalent to the criterion above.

The case of powers of 22 is more special. To handle it, we use a result about the structure of the reduced residue system modulo 2e2^e: every odd aa is uniquely congruent to an integer of the form (−1)s5r mod 2e(-1)^s5^r\bmod 2^e, where s∈{0,1}s\in\{0,1\} and 0≤r<2e−20\le r < 2^{e-2}. This gives the following result:

Theorem

Let k≥2k\ge 2 be an integer, let aa be odd, and let the positive integer m=2em=2^e with e≥2e \ge 2. When kk is odd:

  1. aa is always, modulo mm, a kk-th residue.
  2. aa has exactly one root modulo mm of degree kk.
  3. The number of residue classes modulo mm of degree kk is 2e−12^{e-1}, namely all reduced residue classes.

When kk is even, let d=gcd⁡(k,2e−2)d=\gcd(k,2^{e-2}) and d′=2e−2dd'=\dfrac{2^{e-2}}{d}. Then:

  1. aa is, modulo mm, a kk-th residue if and only if a≡1(mod4)a\equiv 1\pmod 4 and ad′≡1(modm)a^{d'}\equiv 1\pmod m.

  2. If aa is, modulo mm, a kk-th residue, then aa has, modulo mm, exactly 2d2d distinct roots of degree kk, of the form

    x≡±5y0+id′(mod2e−1), 0≤y0<d′, i=0,1,⋯ ,d−1.x \equiv \pm 5^{y_0 + id'} \pmod{2^{e-1}},~ 0 \le y_0 < d',~i = 0, 1,\cdots,d-1.
  3. The number of residue classes modulo mm of degree kk is d′d', and all of them are

    {5di mod m:0≤i<d′}.\{5^{di}\bmod m : 0 \le i < d'\}.
Proof

Since a⊥ma\perp m, we have x⊥mx\perp m. Since both xx and aa are odd, the result above lets us write a≡(−1)s5r(mod2e)a\equiv (-1)^s5^r\pmod{2^e} and x=(−1)z5y(mod2e)x=(-1)^z5^{y}\pmod{2^e}. Because this representation is unique, the congruence equation xk≡a(mod2e)x^k\equiv a\pmod{2^e} is equivalent to the system of linear congruence equations

kz≡s(mod2),ky≡r(mod2e−2).\begin{aligned} kz &\equiv s \pmod{2},\\ ky &\equiv r \pmod{2^{e-2}}. \end{aligned}

Combining this page's analysis of solutions to linear congruence equations gives the structure of the solutions to xk≡a(mod2e)x^k\equiv a\pmod{2^e}. Depending on the parity of kk, there are two cases:

  • When kk is odd, gcd⁡(k,2)=gcd⁡(k,2e−2)=1\gcd(k,2)=\gcd(k,2^{e-2})=1, so both linear congruence equations are solvable for every s,rs,r. Hence the original congruence equation is always solvable for every odd aa.

  • When kk is even, the first equation is solvable if and only if 2∣s2\mid s, and the second is solvable if and only if d=gcd⁡(k,2e−2)∣rd=\gcd(k,2^{e-2})\mid r. Combining them gives all kk-th residue classes. Direct calculation shows that the first condition is equivalent to a≡1(mod4)a\equiv 1\pmod 4; repeating the analysis for odd prime powers shows that the second is equivalent to ad′=1a^{d'}=1. Combining the two gives the criterion in the theorem. The general solutions of the two linear congruence equations are also known:

    z≡0,1(mod2),y≡y0+id′(mod2e−2), 0≤y0<2e−2.\begin{aligned} z &\equiv0,1\pmod 2, \\ y &\equiv y_0 + id' \pmod{2^{e-2}},~ 0\le y_0 < 2^{e-2}. \end{aligned}

    Combining the two gives the general solution of the original equation.

This completely resolves the problem of deciding kk-th residues for different moduli. The Legendre symbol and quadratic reciprocity law for quadratic residues can also be generalized to higher-order residues, but this is difficult and requires concepts such as cyclotomic fields. In algebraic number theory, quadratic reciprocity is ultimately generalized by Artin reciprocity.

Roots of Unity

As a special case of kk-th roots, this section discusses the notion of kk-th (primitive) roots of unity. It can be viewed as the analogue in the complex field C\mathbf C of the notion of kk-th roots of unity in the reduced residue system modulo mm, Zm∗\mathbf Z_m^*, modulo mm. When the modulus mm is suitable, using a primitive root of unity of order kk in place of the complex root ωk\omega_k can accelerate computations.

As in the complex case, we have the following definition:

Roots of Unity Modulo mm of Order kk

For a modulus mm, a root of 11 of order kk is called a root of unity modulo mm of order kk (kk-th root of unity modulo mm). In particular, if xx is a root of unity modulo mm of order kk and is not a root of unity modulo mm of any order k′<kk' < k, then xx is also called a primitive root of unity modulo mm of order kk (kk-th primitive root of unity modulo mm).

Comparing this with the definition of a primitive root, we see that a primitive root gg is, modulo mm, a φ(m)\varphi(m)-th primitive root of unity, where φ(m)\varphi(m) is the Euler totient function.

When, modulo mm, a primitive kk-th root of unity exists, its algebraic properties agree with those of the primitive complex kk-th root of unity ωk\omega_k, so it can replace ωk\omega_k in various computations. For example, applying it to the fast Fourier transform gives the number-theoretic transform over the finite field1.

Properties

Every (primitive) root of unity of every order exists in the complex field. In number theory, however, (primitive) roots of unity do not always exist.

Properties

For a modulus mm, let λ(m)\lambda(m) be its Carmichael function. Then:

  1. For a modulus mm, every integer aa coprime to it is, modulo mm, a δm(a)\delta_m(a)-th primitive root of unity; δm(a)\delta_m(a) is the order of aa modulo mm.
  2. If aa is, modulo mm, a kk-th root of unity and k′k' is any multiple of kk, then aa is also, modulo mm, a k′k'-th root of unity.
  3. If aa is, modulo mm, a kk-th (primitive) root of unity, then aℓa^{\ell} is, modulo mm, a kgcd⁡(k,ℓ)\dfrac{k}{\gcd(k,\ell)}-th (primitive, respectively) root of unity.
  4. For k′k' ranging over the divisors of kk, all primitive roots of unity modulo mm of order k′k' form a partition of the roots of unity modulo mm of order kk. Moreover, for ℓ⊥k\ell\perp k, the map x↦xℓx\mapsto x^\ell is a bijection among the kk-th roots of unity and preserves this partition: it still maps k′∣kk'\mid k-th primitive roots of unity to k′k'-th primitive roots of unity.
  5. Modulo mm, a primitive root of unity of order kk exists if and only if k∣λ(m)k\mid\lambda(m). In particular, a primitive root of unity modulo mm of order λ(m)\lambda(m) exists; it is called a modulo mm λ\lambda-primitive root.
  6. An element aa is, modulo mm, a kk-th root of unity if and only if ak≡1(modm)a^k\equiv 1\pmod{m} and, for every prime factor p∣kp\mid k, ak/p≢1(modm)a^{k/p}\not\equiv 1\pmod{m}.
Proof

By the definition of order, every integer coprime to mm, denoted aa, is, modulo mm, a δm(a)\delta_m(a)-th primitive root of unity; here δm(a)\delta_m(a) is the order of aa modulo mm. Conversely, aa is, modulo mm, a kk-th root of unity, so gcd⁡(ak,m)=1\gcd(a^k,m)=1 and hence gcd⁡(a,m)=1\gcd(a,m)=1. Therefore, aa is a (primitive) root of unity modulo mm if and only if aa is coprime to mm. This proves Property 1.

Directly checking the definition shows that whenever k∣k′k\mid k', ak≡1(modm)a^k\equiv 1\pmod m implies ak′≡1(modm)a^{k'}\equiv 1\pmod m, which is Property 2. By the property of order,

δ(aℓ)=δm(a)gcd⁡(δm(a),ℓ).\delta(a^\ell) = \dfrac{\delta_m(a)}{\gcd(\delta_m(a),\ell)}.

If aa is, modulo mm, a kk-th primitive root of unity, then δm(a)=k\delta_m(a)=k, and substituting directly into the equation above shows that aℓa^\ell is, modulo mm, a kgcd⁡(k,ℓ)\dfrac{k}{\gcd(k,\ell)}-th primitive root of unity. If aa is merely, modulo mm, a kk-th root of unity, suppose it is a k′∣kk'\mid k-th primitive root of unity; then aℓa^\ell is, modulo mm, a k′gcd⁡(k′,ℓ)\dfrac{k'}{\gcd(k',\ell)}-th primitive root of unity. Since k′∣kk'\mid k, we have

k′gcd⁡(k′,ℓ)∣kgcd⁡(k,ℓ),\dfrac{k'}{\gcd(k',\ell)} \mid \dfrac{k}{\gcd(k,\ell)},

By Property 2, aℓa^\ell is therefore, modulo mm, a kgcd⁡(k,ℓ)\dfrac{k}{\gcd(k,\ell)}-th root of unity. This proves Property 3.

For k′∣kk'\mid k, Property 2 implies that every primitive root of unity modulo mm of order k′k' is a root of unity modulo mm of order kk. These sets are pairwise disjoint, so they form a partition. For ℓ⊥k\ell\perp k, we also have ℓ⊥k′\ell\perp k', so for a primitive root of unity modulo mm of order k′k', aa, aℓa^\ell is again a primitive root of unity modulo mm of order k′k'. Let ℓ′=ℓ−1 mod k\ell'=\ell^{-1}\bmod k. One can verify that x↦xℓx\mapsto x^\ell and x↦xℓ′x\mapsto x^{\ell'} are inverse maps, so x↦xℓx\mapsto x^\ell is a bijection. This proves Property 4.

By the properties of the Carmichael function, modulo mm, a λ(m)\lambda(m)-th primitive root of unity always exists; let it be aa, with δm(a)=λ(m)\delta_m(a)=\lambda(m). For k∣λ(m)k\mid\lambda(m), let k′=λ(m)kk'=\dfrac{\lambda(m)}{k}. Then

δm(ak′)=λ(m)(λ(m),k′)=λ(m)k′=k.\delta_m(a^{k'}) = \dfrac{\lambda(m)}{(\lambda(m),k')} = \dfrac{\lambda(m)}{k'} = k.

Thus ak′a^{k'} is a kk-th primitive root of unity. By the definition of the Carmichael function, the order of every x⊥mx\perp m is a divisor of λ(m)\lambda(m). This proves Property 5.

Repeating almost the same proof as for the primitive-root criterion theorem gives Property 6. This criterion is actually checking that δm(a)=k\delta_m(a)=k.

These properties show that, relative to the case where primitive roots exist, modulo mm the λ\lambda-primitive root plays a similar foundational role. Unlike primitive roots, powers of the λ\lambda-primitive root cannot generate all roots of unity modulo mm. Nevertheless, because λ\lambda-primitive roots have a non-negligible density2, if we need to find a primitive kk-th root of unity, we can first find a λ\lambda-primitive root randomly and then obtain a primitive kk-th root of unity by taking a power.

If aa modulo mm has a root of degree kk, one can use, modulo mm, all roots of unity of degree kk to generate all roots of aa modulo mm of degree kk.

Theorem

Let xx be a root of aa modulo mm of order kk. As rr ranges over all roots of unity modulo mm of order kk, xrxr ranges over all roots of aa modulo mm of order kk.

Proof

For two roots of aa modulo mm of order kk, x,yx,y, let r=x−1y mod mr=x^{-1}y\bmod m. Then rr satisfies rk≡1(modm)r^k\equiv 1\pmod m and is, modulo mm, a kk-th root of unity. Conversely, if rr is, modulo mm, a kk-th root of unity, then (xr)k=xkrk≡a(modm)(xr)^{k}= x^kr^k\equiv a\pmod m, so xrxr is, modulo mm, a kk-th root.

Generating all kk-th roots using the kk-th roots of unity is analogous to using the solutions of a homogeneous linear system to generate the general solution of a nonhomogeneous linear system.

The discussion so far has been general. When a primitive root exists, the structure of the roots of unity is simpler:

Theorem

For a modulus mm, suppose a primitive root exists modulo mm and aa is, modulo mm, a primitive root of unity of order kk. Then bb is, modulo mm, a root of unity of order kk if and only if it can be expressed as a power of aa.

Proof

Let gg be a primitive root modulo mm. Then every element coprime to mm can be expressed as a power of gg. Thus, aa is, modulo mm, a primitive root of unity of order kk if and only if

δm(a)=δm(gind⁡ga)=φ(m)gcd⁡(φ(m),ind⁡ga)=k.\delta_m(a) = \delta_m(g^{\operatorname{ind}_ga}) = \dfrac{\varphi(m)}{\gcd(\varphi(m),\operatorname{ind}_ga)} = k.

Similarly, bb is, modulo mm, a root of unity of order kk if and only if

δm(b)=δm(gind⁡gb)=φ(m)gcd⁡(φ(m),ind⁡gb)=k′∣k.\delta_m(b) = \delta_m(g^{\operatorname{ind}_gb}) = \dfrac{\varphi(m)}{\gcd(\varphi(m),\operatorname{ind}_gb)} = k' \mid k.

Therefore,

gcd⁡(φ(m),ind⁡ga)∣gcd⁡(φ(m),ind⁡gb)∣ind⁡gb.\gcd(\varphi(m),\operatorname{ind}_ga) \mid \gcd(\varphi(m),\operatorname{ind}_gb)\mid \operatorname{ind}_gb.

By the analysis of linear congruence equations, this condition is equivalent to the equation

(ind⁡ga)x≡ind⁡gb(modφ(m))(\operatorname{ind}_ga) x \equiv \operatorname{ind}_gb \pmod{\varphi(m)}

Having gg raised to the power given by this condition yields ax≡b(modm)a^x\equiv b\pmod{m}, that is, bb can be expressed as a power of aa.

This theorem shows that, when a primitive root exists, all kk-th roots of unity form a cyclic group, and the primitive kk-th roots of unity are generators of this cyclic group. We will see later that the Tonelli–Shanks algorithm exploits this fact to accelerate the discrete-logarithm part of root extraction.

Extracting Roots Modulo a Modulus

Finally, this article discusses how to find kk-th roots. For k=2k=2, there are many efficient algorithms for extracting square roots modulo a modulus. For general kk, however, no polynomial-time algorithm is known. This section introduces two common algorithms that find a root in O(m1/2)O(m^{1/2}) and O(m1/4+ε)O(m^{1/4+\varepsilon}) time, respectively, for degree kk. The Chinese remainder theorem can always reduce the problem to prime-power moduli, so this section focuses on the prime-power case.

Naive Algorithm

The preceding analysis of the properties of kk-th residues has already indicated a method for finding kk-th roots modulo a prime power. Strictly speaking, the case solved above is when the radicand aa is coprime to the modulus mm. The algorithm can be summarized as follows:

  • When m=pem=p^e is an odd prime power, let the primitive root of mm be gg. Then the equation xk≡a(modm)x^k\equiv a\pmod m can be converted into the linear congruence equation

    ky≡ind⁡ga(modφ(m)).ky \equiv \operatorname{ind}_g a \pmod{\varphi(m)}.

    Here, ind⁡ga\operatorname{ind}_g a can be found using the BSGS algorithm, and the solutions of the linear congruence equation yield all aa's kk-th roots x≡gy(modm)x\equiv g^y\pmod m.

    There is also a similar approach. Again let x≡gy(modm)x\equiv g^y\pmod m; by rewriting,

    xk≡(gk)y≡a(modm)x^k \equiv (g^k)^y \equiv a \pmod m

    This becomes finding the discrete logarithm with base gkg^k of aa. A set of particular solutions can likewise be found using BSGS. The general solution can be obtained from the solution expression above: multiply the particular solution by every root of unity of degree kk.

    Whichever approach is used, when the primitive root is known, the complexity of finding one solution is O(m1/2)O(m^{1/2}). Since a primitive root can be found in o(m1/2)o(m^{1/2}) time, the total complexity remains O(m1/2)O(m^{1/2}).

  • When m=2em=2^e and e∈N+e\in\mathbf N_+, first find the exponents in a≡(−1)s5r(modm)a\equiv (-1)^s5^r\pmod m, namely s,rs,r. Of these two exponents, ss can be determined in O(1)O(1) time:

    s={0,a≡1(mod4),1,a≡3(mod4).s = \begin{cases}0, & a\equiv 1\pmod 4, \\ 1, & a\equiv 3\pmod 4.\end{cases}

    The value r=ind⁡5((−1)sa)r=\operatorname{ind}_5((-1)^sa) can be found using BSGS in O(m1/2)O(m^{1/2}) time. Next, solve the system of linear congruence equations:

    kz≡s(mod2),ky≡r(mod2e−2).\begin{aligned} kz &\equiv s \pmod{2},\\ ky &\equiv r \pmod{2^{e-2}}. \end{aligned}

    The general solution (z,y)(z,y) of this linear system is easy to obtain, and x=(−1)z5yx=(-1)^z5^y is the desired root. The complexity of finding one solution with this algorithm is still O(m1/2)O(m^{1/2}).

Of course, in the no-solution case, the criterion described above can be used to decide this quickly in O(log⁡m)O(\log m) time, without checking during the solving process.

The following is a reference implementation for finding a kk-th root modulo a prime (the code is only illustrative; its time complexity is too high to pass the problem):

Template Problem Library Checker - Kth Root (Mod), Reference Implementation
// Submission (TLE): https://judge.yosupo.jp/submission/320582
#include <algorithm>
#include <cmath>
#include <iostream>
#include <tuple>
#include <unordered_map>
#include <vector>

struct PrimePower {
  int p, e, pe;

  PrimePower(int p, int e, int pe) : p(p), e(e), pe(pe) {}
};

// Factorization.
auto factorize(int n) {
  std::vector<PrimePower> ans;
  for (int x = 2; x * x <= n; ++x) {
    int e = 0, pe = 1;
    for (; n % x == 0; n /= x, ++e, pe *= x);
    if (e) ans.emplace_back(x, e, pe);
  }
  if (n > 1) ans.emplace_back(n, 1, n);
  return ans;
}

// Binary exponentiation.
int pow(int a, int b, int m = 0) {
  int res = 1;
  for (; b; b >>= 1) {
    if (b & 1) res = m ? (long long)res * a % m : res * a;
    a = m ? (long long)a * a % m : a * a;
  }
  return res;
}

// Find a primitive root modulo prime.
int primitive_root(int p) {
  std::vector<int> exp;
  for (auto factor : factorize(p - 1)) {
    exp.push_back((p - 1) / factor.p);
  }
  int ans = 0;
  bool succ = false;
  while (!succ) {
    ++ans;
    succ = true;
    for (int b : exp) {
      if (pow(ans, b, p) == 1) {
        succ = false;
        break;
      }
    }
  }
  return ans;
}

// Discrete logarithm. (BSGS Algorithm)
int log(int g, int a, int m) {
  int b = std::sqrt(m + 0.25l) + 1;
  std::unordered_map<int, int> mp;
  int po0 = a % m, po1 = 1;
  for (int i = 0; i < b; ++i) {
    mp[po0] = i;
    po0 = (long long)po0 * g % m;
  }
  po0 = pow(g, b, m);
  for (int j = 1; j <= b; ++j) {
    po1 = (long long)po1 * po0 % m;
    if (mp.count(po1)) return j * b - mp[po1];
  }
  return -1;
}

// Extended Euclidean Algorithm.
int ex_gcd(int a, int b, int& x, int& y) {
  if (!b) {
    x = 1;
    y = 0;
    return a;
  } else {
    int d = ex_gcd(b, a % b, y, x);
    y -= a / b * x;
    return d;
  }
}

// Solves the linear congruence equation: Ax = B mod N.
// Return the least nonnegative solution and the common difference.
std::pair<int, int> solve_linear(int a, int b, int n) {
  int x, y;
  int d = ex_gcd(a, n, x, y);
  if (b % d) return {-1, -1};
  n /= d;
  x = ((long long)x * (b / d) % n + n) % n;
  return {x, n};
}

// Subroutine: Find a K-th root with a primitive root G known.
int calc(int g, int k, int a, int p) {
  int ind = log(g, a, p);
  if (ind == -1) return -1;
  int y0, d;
  std::tie(y0, d) = solve_linear(k, ind, p - 1);
  if (y0 == -1) return -1;
  return pow(g, y0, p);
}

// Find a K-th root of A modulo prime P.
int kth_roots_mod_p(int k, int a, int p) {
  a %= p;
  if (k == 0) return a == 1 ? 0 : -1;
  if (a == 0) return 0;
  return calc(primitive_root(p), k, a, p);
}

void solve() {
  int k, y, p;
  std::cin >> k >> y >> p;
  std::cout << kth_roots_mod_p(k, y, p) << '\n';
}

int main() {
  int t;
  std::cin >> t;
  for (; t; --t) {
    solve();
  }
}

Improved Tonelli–Shanks Algorithm

A suitable generalization of the Tonelli–Shanks algorithm for extracting square roots modulo a modulus can solve root extraction modulo prime powers. One relatively direct generalization is the Adleman–Manders–Miller algorithm3, but its complexity is still not good enough4. This section introduces an improved Tonelli–Shanks algorithm proposed by sugarknri, Min_25, 37zigen, and others. It can find, in O(m1/4+ε)O(m^{1/4+\varepsilon}) time, a kk-th root.

The central idea of the Tonelli–Shanks algorithm is to move the discrete-logarithm computation into a group of order 2e2^e, thereby reducing the time complexity. Similarly, a discrete logarithm in a group of prime-power order pep^e can be computed relatively efficiently, but the complexity is Ω(p)\Omega\left(\sqrt{p}\right). The Adleman–Manders–Miller algorithm decomposes the computation of a kk-th root into discrete logarithms in several groups of prime-power order, but, limited by kk's largest prime factor pmax(k)p_\text{max}(k), its complexity is still Ω(pmax(k))\Omega\left(\sqrt{p_\text{max}(k)}\right). The algorithm in this section improves the process further, avoiding discrete logarithms for large prime factors and controlling the overall complexity at O(m1/4+ε)O(m^{1/4+\varepsilon}).

Process

Consider, for a prime power mm, computing the root of aa of degree kk, that is, solving the congruence equation:

xk≡a(modm).x^k \equiv a \pmod m.

For the case m=2em=2^e, we additionally need a≡1(mod4)a\equiv 1\pmod{4}, so that aa can be written as a power of g=5g=5. As discussed earlier, modulo 2e2^e, extracting a kk-th root can always be reduced to this case. When handling this case, namely 2e2^e, every occurrence of φ(m)\varphi(m) mentioned in this section should be replaced by δm(5)=2e−2\delta_m(5)=2^{e-2}.

First, the problem can be reduced to the case where the root degree divides φ(m)\varphi(m). Let d=gcd⁡(k,φ(m))d=\gcd(k,\varphi(m)). By the properties of kk-th residues, when aa modulo mm is a kk-th residue, then aa is always, modulo mm, a φ(m)d\dfrac{\varphi(m)}{d}-th root of unity. By the properties of roots of unity, for any ℓ⊥φ(m)d\ell\perp\dfrac{\varphi(m)}{d}, the map x↦xℓx\mapsto x^{\ell} is a bijection among the φ(m)d\dfrac{\varphi(m)}{d}-th roots of unity. Therefore, we can take

ℓ=(kd)−1 mod φ(m)d.\ell = \left(\dfrac{k}{d}\right)^{-1}\bmod\dfrac{\varphi(m)}{d}.

Raising both sides of the original congruence equation to the power ℓ\ell gives

xd≡xkℓ≡aℓ=:b(modm).x^d\equiv x^{k\ell} \equiv a^{\ell} =: b \pmod{m}.

The leftmost congruence uses Euler's theorem and the following congruence relation (where c∈Zc\in\mathbf Z):

kℓ=d(kdℓ)=d(cφ(m)d+1)≡d(modφ(m)).k\ell = d\left(\frac{k}{d}\ell\right) = d\left(c\dfrac{\varphi(m)}{d}+1\right) \equiv d \pmod{\varphi(m)}.

For the transformed problem, consider the prime factorization of dd:

d=∏p∈Ppe.d = \prod_{p\in\mathbf P}p^e.

Starting from b=aℓb=a^\ell, for each pe≠1p^e\neq 1, successively extract a pep^e-th root; the result is the root of bb of degree dd, which is the root of aa of degree kk.

Finally, the problem becomes solving the following equation:

xpe≡b(modm).x^{p^e} \equiv b \pmod m.

Suppose φ(m)=psr\varphi(m)=p^sr and p⊥rp\perp r. Let q∈N+q\in\mathbf N_+ be a solution of qr≡−1(modpe)qr\equiv -1\pmod{p^e}. Since bb is an rps−erp^{s-e}-th root of unity, bqrb^{qr} must be a ps−ep^{s-e}-th root of unity. Let ζ\zeta be, modulo mm, a primitive psp^s-th root of unity. Then ζpe\zeta^{p^e} is a primitive ps−ep^{s-e}-th root of unity, so there exists h∈Nh\in\mathbf N such that bqr≡ζhpe(modm)b^{qr}\equiv \zeta^{hp^{e}}\pmod{m}. Therefore, direct verification shows that

x≡b(qr+1)/peζ−h(modm)x\equiv b^{(qr+1)/p^e}\zeta^{-h} \pmod{m}

is a root of bb modulo mm of degree pep^e.

To compute xx, find, modulo mm, a pp-th nonresidue η\eta. By the properties above, it is enough to choose η⊥m\eta\perp m at random and check that ηφ(m)/p mod m≠1\eta^{\varphi(m)/p}\bmod{m}\neq 1. The density of such numbers is

φ(m)m(1−1p)≥14.\dfrac{\varphi(m)}{m}\left(1-\dfrac{1}{p}\right) \ge \dfrac{1}{4}.

Thus, in expectation, no more than 44 random integers are needed to find one. Note that ηrps−1≢1(modm)\eta^{rp^{s-1}}\not\equiv 1\pmod m and ηrps≡1(modm)\eta^{rp^s}\equiv 1\pmod m. Therefore, if we set ζ=ηr mod m\zeta=\eta^r\bmod m and ξ=ηrps−1 mod m\xi=\eta^{rp^{s-1}}\bmod m, they are respectively primitive psp^s-th and pp-th roots of unity.

Finally, we need to compute h∈Nh\in\mathbf N. Clearly, we can take h<ps−eh < p^{s-e}. Consider hh in base pp:

h=∑j=0s−e−1hjpj=h0+h1p+h2p2+⋯ .h = \sum_{j=0}^{s-e-1}h_jp^j = h_0 + h_1p + h_2p^2 +\cdots.

Compute these digits one by one. Once the first jj digits have been computed, we necessarily have

(bqrζ−pe(h0+h1p+⋯+hj−1pj−1))ps−e−j−1≡ζhjps−1≡ξhj(modm).\left(b^{qr}\zeta^{-p^e(h_0+h_1p+\cdots + h_{j-1}p^{j-1})}\right)^{p^{s-e-j-1}} \equiv \zeta^{h_jp^{s-1}} \equiv \xi^{h_j} \pmod{m}.

Thus, hjh_j can be found by computing a discrete logarithm to the base ξ\xi. To obtain better time complexity, use BSGS. In total, (s−e)(s-e) discrete logarithms must be computed. If BB powers of ξ\xi are precomputed, the time complexity of one discrete-logarithm computation is O(p/B)O(p/B), and the total time complexity is

O(B+(s−e)pB).O\left(B+(s-e)\dfrac{p}{B}\right).

When B=(s−e)pB=\sqrt{(s-e)p}, the total time complexity is minimized at O((s−e)p)O\left(\sqrt{(s-e)p}\right). After obtaining hh, substitute it into the expression for xx above to obtain a particular solution.

Time Complexity

The time complexity of this algorithm is O(m1/4+ε)O(m^{1/4+\varepsilon}). In this complexity discussion, we always assume that one multiplication takes O(1)O(1) time, and that exponentiation always uses Euler's theorem to reduce the exponent, so computing any individual power takes O(log⁡m)O(\log m) time.

First consider computing a single pep^e-th root. Finding a pp-th nonresidue requires checking an expected O(1)O(1) numbers, for a total time complexity of O(log⁡m)O(\log m). Computing each of s,r,ζ,η,bqrs,r,\zeta,\eta,b^{qr} takes only O(log⁡m)O(\log m) time. When computing hh, each digit requires O(log⁡m)O(\log m) time for exponentiation, and there are (s−e)(s-e) digits, so the total time complexity is O((s−e)log⁡m)O((s-e)\log m). As stated above, preprocessing for the discrete logarithms and the (s−e)(s-e) queries together take O((s−e)p)O\left(\sqrt{(s-e)p}\right) time. Since s−e∈O(log⁡m)s-e\in O(\log m), computing a single pep^e-th root takes O(p1/2+ε)O(p^{1/2+\varepsilon}) time. In particular, when s=es=e, the time complexity can be reduced further to O(log⁡m)O(\log m).

We can then consider the total time complexity of the algorithm. Computing φ(m),d,ℓ\varphi(m),d,\ell all takes O(log⁡m)O(\log m) time. Next, factor d=∏pped=\prod_p{p^e}; this can be done in O(m1/4)O(m^{1/4}) time using Pollard Rho. Finally, the total time for successively computing pep^e-th roots is

O(∑e<sp1/2+ε).O\left(\sum_{e < s}p^{1/2+\varepsilon}\right).

Since e<se < s, every prime factor pp occurs in φ(m)\varphi(m) at least 22 times, so we necessarily have p<m1/2p < m^{1/2}. Therefore, the total time complexity is O(m1/4+ε)O(m^{1/4+\varepsilon}).

In fact, in this situation we can still achieve O(m1/4+ε)O(m^{1/4+\varepsilon}) time without using Pollard Rho to factor the integer. It is enough to factor dd by trial division, enumerating only prime factors no greater than m1/4m^{1/4}. Let the integer obtained after removing these small prime factors be zz. For zz's prime factor p>m1/4p > m^{1/4}, we necessarily have νp(φ(m))<4\nu_p(\varphi(m)) < 4, where νp(n)\nu_p(n) denotes, for nn, the exponent of pp in the prime factorization of the integer. Since we only need to consider

1≤e=νp(d)<s=νp(φ(m))<41 \le e = \nu_p(d) < s = \nu_p(\varphi(m)) < 4

the case described above: at most one prime factor pp can satisfy this condition; otherwise, each would occur in φ(m)\varphi(m) at least 22 times, making the total product exceed mm. To isolate this one (possibly existing) large prime factor, compute

p⋆=gcd⁡(z,φ(m)z)=∏p:νp(d)<νp(φ(m))pmin⁡{νp(d),νp(φ(m))−νp(d)}.p^\star=\gcd\left(z,\dfrac{\varphi(m)}{z}\right) = \prod_{p : \nu_p(d) < \nu_p(\varphi(m))}p^{\min\{\nu_p(d),\nu_p(\varphi(m))-\nu_p(d)\}}.

Enumerating all possible values of νp(d),νp(φ(m))\nu_p(d),\nu_p(\varphi(m)) shows that the exponent of pp in the product is always 11, so the result is exactly the unique large prime factor p⋆p^\star (if one exists). The remaining part z/p⋆z/p^\star can contain only prime factors satisfying e=se=s, so it does not need to be factored further.

The following is a reference implementation for finding a kk-th root modulo a prime:

Template Problem Library Checker - Kth Root (Mod), Reference Implementation
#include <algorithm>
#include <cmath>
#include <iostream>
#include <random>
#include <tuple>
#include <unordered_map>
#include <vector>

std::mt19937 rng(std::random_device{}());

// Binary exponentiation.
int pow(int a, int b, int m = 0) {
  int res = 1;
  for (; b; b >>= 1) {
    if (b & 1) res = m ? (long long)res * a % m : res * a;
    a = m ? (long long)a * a % m : a * a;
  }
  return res;
}

// Find a P-th non-residue mod M.
int non_residue(int p, int m, int phi) {
  std::uniform_int_distribution<int> dis(1, m - 1);
  while (true) {
    int c = dis(rng);
    if (pow(c, phi / p, m) != 1) return c;
  }
  return -1;
}

// Euclidean Algorithm.
int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }

// Extended Euclidean Algorithm.
int ex_gcd(int a, int b, int& x, int& y) {
  if (!b) {
    x = 1;
    y = 0;
    return a;
  } else {
    int d = ex_gcd(b, a % b, y, x);
    y -= a / b * x;
    return d;
  }
}

// Returns the modular inverse of A modulo M.
// Assumes that gcd(A, M) = 1, so the inverse exists.
int inv(int a, int m) {
  int x, y;
  ex_gcd(a, m, x, y);
  return (x % m + m) % m;
}

// Subroutine: Find a P^E-th root of A mod M.
int peth_root_mod_m(int p, int e, int a, int m, int phi) {
  int s = 0, r = phi, pe = pow(p, e);
  for (; r % p == 0; r /= p, ++s);
  int q = pe - inv(r, pe);
  int ans = pow(a, ((long long)q * r + 1) / pe % phi, m);
  int eta = non_residue(p, m, phi);
  std::unordered_map<int, int> mp;
  int zeta = pow(eta, r, m);
  int xi = pow(eta, phi / p, m);
  // Precompute powers for BSGS.
  int B = std::sqrt((s - e) * p + 0.25l) + 1;
  int pB = p / B + 1;
  int po0 = pow(xi, pB, m);
  for (int j = 1, po1 = 1; j <= B; ++j) {
    po1 = (long long)po1 * po0 % m;
    mp[po1] = j;
  }
  // Compute p-adic digits of h.
  for (int j = 0; j < s - e; ++j) {
    int err = (long long)pow(ans, pe, m) * inv(a, m) % m;
    int xi_hj = pow(err, pow(p, s - e - j - 1), m);
    long long hj = 0;
    // BSGS query.
    for (int i = 1; i <= pB; ++i) {
      xi_hj = (long long)xi_hj * xi % m;
      if (mp.count(xi_hj)) {
        hj = mp[xi_hj] * pB - i;
        break;
      }
    }
    ans = (long long)ans * pow(zeta, phi - hj * pow(p, j) % phi, m) % m;
  }
  return ans;
}

// Find a K-th root of A modulo prime P.
int kth_root_mod_p(int k, int a, int p) {
  a %= p;
  if (k == 0) return a == 1 ? 0 : -1;
  if (a == 0) return 0;
  int d = gcd(k, p - 1);
  if (pow(a, (p - 1) / d, p) != 1) return -1;
  a = pow(a, inv(k / d, (p - 1) / d), p);
  for (int dp = 2; dp * dp <= d && dp * dp * dp * dp < p; ++dp) {
    if (d % dp == 0) {
      int de = 0;
      for (; d % dp == 0; d /= dp, ++de);
      a = peth_root_mod_m(dp, de, a, p, p - 1);
    }
  }
  if (d != 1) {
    int dp = gcd(d, (p - 1) / d), de = 0;
    if (dp != 1) {
      for (; d % dp == 0; d /= dp, ++de);
      a = peth_root_mod_m(dp, de, a, p, p - 1);
    }
    if (d != 1) a = peth_root_mod_m(d, 1, a, p, p - 1);
  }
  return a;
}

void solve() {
  int k, y, p;
  std::cin >> k >> y >> p;
  std::cout << kth_root_mod_p(k, y, p) << '\n';
}

int main() {
  int t;
  std::cin >> t;
  for (; t; --t) {
    solve();
  }
}

Handling the General Case

Consider the general case, still with modulus mm, a prime power pep^e, but now gcd⁡(a,m)>1\gcd(a,m)>1. If a≡0(modm)a\equiv 0\pmod{m}, then

x=p⌈e/k⌉ℓ(modpe), ℓ=0,1,⋯ ,pe−⌈e/k⌉−1x = p^{\lceil e/k \rceil}\ell\pmod{p^e},~\ell=0,1,\cdots,p^{e-\lceil e/k\rceil}-1

are all solutions of the original equation. Next, consider the case a≢0(modm)a\not\equiv 0\pmod{m}. Let a=psa′a = p^sa' with p⊥a′p\perp a'. Then, writing x=pzx′x=p^zx' with p⊥x′p\perp x', we have

xk=pkz(x′)k≡psa′(modpe).x^k = p^{kz}(x')^k\equiv p^sa'\pmod{p^e}.

Since (x′)k⊥p(x')^k\perp p, this holds if and only if kz=skz = s and (x′)k≡a′(modpe−s)(x')^k\equiv a'\pmod{p^{e-s}}. The first equation has a solution if and only if k∣sk\mid s, in which case z=skz=\dfrac{s}{k}; the second equation has already been solved. Note that the modulus of the general solution of the second equation differs from that of the general solution of the original equation, so each solution x′x' of the second equation corresponds to several solutions of the original equation:

x≡ps/k(x′+ℓpe−s)(modpe), ℓ=0,1,⋯ ,ps−s/k−1.x \equiv p^{s/k}(x' + \ell p^{e-s})\pmod{p^e},~\ell = 0,1,\cdots, p^{s-s/k}-1.

The following is a reference implementation for finding all kk-th roots modulo an arbitrary modulus:

Template Problem Luogu P5668 [Template] N-th Residue, Reference Code

Naive Algorithm

#include <algorithm>
#include <cmath>
#include <iostream>
#include <tuple>
#include <unordered_map>
#include <vector>

struct PrimePower {
  int p, e, pe;

  PrimePower(int p, int e, int pe) : p(p), e(e), pe(pe) {}
};

// Factorization.
auto factorize(int n) {
  std::vector<PrimePower> ans;
  for (int x = 2; x * x <= n; ++x) {
    int e = 0, pe = 1;
    for (; n % x == 0; n /= x, ++e, pe *= x);
    if (e) ans.emplace_back(x, e, pe);
  }
  if (n > 1) ans.emplace_back(n, 1, n);
  return ans;
}

// Binary exponentiation.
int pow(int a, int b, int m = 0) {
  int res = 1;
  for (; b; b >>= 1) {
    if (b & 1) res = m ? (long long)res * a % m : res * a;
    a = m ? (long long)a * a % m : a * a;
  }
  return res;
}

// Find a primitive root modulo odd prime power.
int primitive_root(PrimePower pp) {
  std::vector<int> exp;
  int phi = pp.pe / pp.p * (pp.p - 1);
  for (auto factor : factorize(pp.p - 1)) {
    exp.push_back(phi / factor.p);
  }
  if (pp.e != 1) exp.push_back(phi / pp.p);
  int ans = 0;
  bool succ = false;
  while (!succ) {
    ++ans;
    succ = true;
    for (int b : exp) {
      if (pow(ans, b, pp.pe) == 1) {
        succ = false;
        break;
      }
    }
  }
  return ans;
}

// Discrete logarithm. (BSGS Algorithm)
int log(int g, int a, int m) {
  int b = std::sqrt(m + 0.25l) + 1;
  std::unordered_map<int, int> mp;
  int po0 = a % m, po1 = 1;
  for (int i = 0; i < b; ++i) {
    mp[po0] = i;
    po0 = (long long)po0 * g % m;
  }
  po0 = pow(g, b, m);
  for (int j = 1; j <= b; ++j) {
    po1 = (long long)po1 * po0 % m;
    if (mp.count(po1)) return j * b - mp[po1];
  }
  return -1;
}

// Extended Euclidean Algorithm.
int ex_gcd(int a, int b, int& x, int& y) {
  if (!b) {
    x = 1;
    y = 0;
    return a;
  } else {
    int d = ex_gcd(b, a % b, y, x);
    y -= a / b * x;
    return d;
  }
}

// Returns the modular inverse of A modulo M.
// Assumes that gcd(A, M) = 1, so the inverse exists.
int inv(int a, int m) {
  int x, y;
  ex_gcd(a, m, x, y);
  return (x % m + m) % m;
}

// Solves the linear congruence equation: Ax = B mod N.
// Return the least nonnegative solution and the common difference.
std::pair<int, int> solve_linear(int a, int b, int n) {
  int x, y;
  int d = ex_gcd(a, n, x, y);
  if (b % d) return {-1, -1};
  n /= d;
  x = ((long long)x * (b / d) % n + n) % n;
  return {x, n};
}

// Subroutine: Find all the K-th roots with a primitive root G known.
std::vector<int> calc(int g, int k, int a, int p, int pe) {
  int ind = log(g, a, pe);
  if (ind == -1) return {};
  int mm = p == 2 ? pe / 4 : pe / p * (p - 1);
  int y0, d;
  std::tie(y0, d) = solve_linear(k, ind, mm);
  if (y0 == -1) return {};
  int ans = pow(g, y0, pe), po = pow(g, d, pe);
  std::vector<int> res(mm / d);
  for (auto& x : res) {
    x = ans;
    ans = (long long)ans * po % pe;
  }
  return res;
}

// Find all the K-th roots of A modulo prime power P^E.
std::vector<int> kth_roots_mod_pe(int k, int a, PrimePower pp) {
  int p = pp.p, e = pp.e, pe = pp.pe;
  a %= pe;
  if (a == 0) {
    int d = pow(p, (e - 1) / k + 1);
    std::vector<int> res(pe / d);
    for (int i = 0; i < pe / d; ++i) {
      res[i] = i * d;
    }
    return res;
  }
  int s = 0;
  for (; a % p == 0; a /= p, ++s);
  if (s % k) return {};
  int psk = pow(p, s / k), pss = pow(p, s - s / k), pes = pow(p, e - s);
  std::vector<int> res;
  if (p != 2) {
    int g = primitive_root(PrimePower(p, e - s, pes));
    res = calc(g, k, a, p, pes);
  } else if (pes == 2) {
    res.push_back(a);
  } else if (k & 1) {
    int z = a % 4 == 3;
    a = z ? pes - a : a;
    res = calc(5, k, a, p, pes);
    if (z) {
      for (auto& x : res) x = pes - x;
    }
  } else {
    if (a % 4 == 3) return {};
    res = calc(5, k, a, p, pes);
    int m = res.size();
    res.reserve(m * 2);
    for (int i = 0; i < m; ++i) {
      res.push_back(pes - res[i]);
    }
  }
  int m = res.size();
  res.reserve(m * pss);
  for (int j = 1; j < pss; ++j) {
    for (int i = 0; i < m; ++i) {
      res.push_back(res.end()[-m] + pes);
    }
  }
  for (auto& x : res) x *= psk;
  return res;
}

// Find all the K-th roots of A modulo positive integer M.
std::vector<int> kth_roots_mod_m(int k, int a, int m) {
  auto factors = factorize(m);
  int m0 = 0;
  std::vector<std::vector<int>> sols;
  for (const auto& pp : factors) {
    sols.push_back(kth_roots_mod_pe(k, a, pp));
    if (sols.back().empty()) return {};
  }
  std::vector<int> ans;
  for (int i = 0; i < (int)factors.size(); ++i) {
    auto pp = factors[i];
    if (!i) {
      m0 = pp.pe;
      ans = sols[i];
    } else {
      long long m1 = pp.pe * inv(pp.pe, m0);
      long long m2 = m0 * inv(m0, pp.pe);
      m0 *= pp.pe;
      std::vector<int> _ans;
      _ans.reserve(ans.size() * sols[i].size());
      for (auto x : ans) {
        for (auto y : sols[i]) {
          _ans.push_back((m1 * x + m2 * y) % m0);
        }
      }
      ans.swap(_ans);
    }
  }
  return ans;
}

void solve() {
  int n, m, k;
  std::cin >> n >> m >> k;
  auto ans = kth_roots_mod_m(n, k, m);
  if (ans.empty()) {
    std::cout << 0 << '\n';
    return;
  }
  std::cout << ans.size() << '\n';
  std::sort(ans.begin(), ans.end());
  for (auto x : ans) std::cout << x << ' ';
  std::cout << '\n';
}

int main() {
  int t;
  std::cin >> t;
  for (; t; --t) {
    solve();
  }
}

Improved Tonelli–Shanks algorithm

#include <algorithm>
#include <cmath>
#include <iostream>
#include <random>
#include <tuple>
#include <unordered_map>
#include <vector>

std::mt19937 rng(std::random_device{}());

struct PrimePower {
  int p, e, pe;

  PrimePower(int p, int e, int pe) : p(p), e(e), pe(pe) {}
};

// Factorization.
auto factorize(int n) {
  std::vector<PrimePower> ans;
  for (int x = 2; x * x <= n; ++x) {
    int e = 0, pe = 1;
    for (; n % x == 0; n /= x, ++e, pe *= x);
    if (e) ans.emplace_back(x, e, pe);
  }
  if (n > 1) ans.emplace_back(n, 1, n);
  return ans;
}

// Binary exponentiation.
int pow(int a, int b, int m = 0) {
  int res = 1;
  for (; b; b >>= 1) {
    if (b & 1) res = m ? (long long)res * a % m : res * a;
    a = m ? (long long)a * a % m : a * a;
  }
  return res;
}

// Find a primitive root modulo odd prime power.
int primitive_root(PrimePower pp) {
  std::vector<int> exp;
  int phi = pp.pe / pp.p * (pp.p - 1);
  for (auto factor : factorize(pp.p - 1)) {
    exp.push_back(phi / factor.p);
  }
  if (pp.e != 1) exp.push_back(phi / pp.p);
  int ans = 0;
  bool succ = false;
  while (!succ) {
    ++ans;
    succ = true;
    for (int b : exp) {
      if (pow(ans, b, pp.pe) == 1) {
        succ = false;
        break;
      }
    }
  }
  return ans;
}

// Euclidean Algorithm.
int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }

// Extended Euclidean Algorithm.
int ex_gcd(int a, int b, int& x, int& y) {
  if (!b) {
    x = 1;
    y = 0;
    return a;
  } else {
    int d = ex_gcd(b, a % b, y, x);
    y -= a / b * x;
    return d;
  }
}

// Returns the modular inverse of A modulo M.
// Assumes that gcd(A, M) = 1, so the inverse exists.
int inv(int a, int m) {
  int x, y;
  ex_gcd(a, m, x, y);
  return (x % m + m) % m;
}

// Find a P-th non-residue mod M.
int non_residue(int p, int m, int phi) {
  std::uniform_int_distribution<int> dis(1, m - 1);
  while (true) {
    int c = dis(rng);
    if (gcd(c, m) == 1 && pow(c, phi / p, m) != 1) return c;
  }
  return -1;
}

// Subroutine: Find a P^E-th root of A mod M.
int peth_root_mod_m(int p, int e, int a, int m, int phi) {
  if (m == 2) return 1;
  int s = 0, r = phi, pe = pow(p, e);
  for (; r % p == 0; r /= p, ++s);
  int q = pe - inv(r, pe);
  int ans = pow(a, ((long long)q * r + 1) / pe % phi, m);
  int eta = non_residue(p, m, phi);
  std::unordered_map<int, int> mp;
  int zeta = pow(eta, r, m);
  int xi = pow(eta, phi / p, m);
  // Precompute powers for BSGS.
  int B = std::sqrt((s - e) * p + 0.25l) + 1;
  int pB = pe / B + 1;
  int po0 = pow(xi, pB, m);
  for (int j = 1, po1 = 1; j <= B; ++j) {
    po1 = (long long)po1 * po0 % m;
    mp[po1] = j;
  }
  // Compute p-adic digits of h.
  for (int j = 0; j < s - e; ++j) {
    int err = (long long)pow(ans, pe, m) * inv(a, m) % m;
    int xi_hj = pow(err, pow(p, s - e - j - 1), m);
    long long hj = 0;
    // BSGS query.
    for (int i = 1; i <= pB; ++i) {
      xi_hj = (long long)xi_hj * xi % m;
      if (mp.count(xi_hj)) {
        hj = mp[xi_hj] * pB - i;
        break;
      }
    }
    ans = (long long)ans * pow(zeta, phi - hj * pow(p, j) % phi, m) % m;
  }
  return ans;
}

// Find a K-th root of A modulo prime P^E.
int kth_root_mod_pe(int k, int a, int pe, int phi) {
  a %= pe;
  if (k == 0) return a == 1 ? 0 : -1;
  if (a == 0) return 0;
  int d = gcd(k, phi);
  if (pow(a, phi / d, pe) != 1) return -1;
  a = pow(a, inv(k / d, phi / d), pe);
  for (int dp = 2; dp * dp <= d && dp * dp * dp * dp < pe; ++dp) {
    if (d % dp == 0) {
      int de = 0;
      for (; d % dp == 0; d /= dp, ++de);
      a = peth_root_mod_m(dp, de, a, pe, phi);
    }
  }
  if (d != 1) {
    int dp = gcd(d, phi / d), de = 0;
    if (dp != 1) {
      for (; d % dp == 0; d /= dp, ++de);
      a = peth_root_mod_m(dp, de, a, pe, phi);
    }
    if (d != 1) a = peth_root_mod_m(d, 1, a, pe, phi);
  }
  return a;
}

// Subroutine: Find all the K-th roots with a primitive root G known.
std::vector<int> calc(int g, int k, int a, int p, int pe) {
  int mm = p == 2 ? pe / 4 : pe / p * (p - 1);
  int ans = kth_root_mod_pe(k, a, pe, mm);
  if (ans == -1) return {};
  int d = mm / gcd(k, mm);
  int po = pow(g, d, pe);
  std::vector<int> res(mm / d);
  for (auto& x : res) {
    x = ans;
    ans = (long long)ans * po % pe;
  }
  return res;
}

// Find all the K-th roots of A modulo prime power P^E.
std::vector<int> kth_roots_mod_pe(int k, int a, PrimePower pp) {
  int p = pp.p, e = pp.e, pe = pp.pe;
  a %= pe;
  if (a == 0) {
    int d = pow(p, (e - 1) / k + 1);
    std::vector<int> res(pe / d);
    for (int i = 0; i < pe / d; ++i) {
      res[i] = i * d;
    }
    return res;
  }
  int s = 0;
  for (; a % p == 0; a /= p, ++s);
  if (s % k) return {};
  int psk = pow(p, s / k), pss = pow(p, s - s / k), pes = pow(p, e - s);
  std::vector<int> res;
  if (p != 2) {
    int g = primitive_root(PrimePower(p, e - s, pes));
    res = calc(g, k, a, p, pes);
  } else if (pes == 2) {
    res.push_back(a);
  } else if (k & 1) {
    int z = a % 4 == 3;
    a = z ? pes - a : a;
    res = calc(5, k, a, p, pes);
    if (z) {
      for (auto& x : res) x = pes - x;
    }
  } else {
    if (a % 4 == 3) return {};
    res = calc(5, k, a, p, pes);
    int m = res.size();
    res.reserve(m * 2);
    for (int i = 0; i < m; ++i) {
      res.push_back(pes - res[i]);
    }
  }
  int m = res.size();
  res.reserve(m * pss);
  for (int j = 1; j < pss; ++j) {
    for (int i = 0; i < m; ++i) {
      res.push_back(res.end()[-m] + pes);
    }
  }
  for (auto& x : res) x *= psk;
  return res;
}

// Find all the K-th roots of A modulo positive integer M.
std::vector<int> kth_roots_mod_m(int k, int a, int m) {
  auto factors = factorize(m);
  int m0 = 0;
  std::vector<std::vector<int>> sols;
  for (const auto& pp : factors) {
    sols.push_back(kth_roots_mod_pe(k, a, pp));
    if (sols.back().empty()) return {};
  }
  std::vector<int> ans;
  for (int i = 0; i < (int)factors.size(); ++i) {
    auto pp = factors[i];
    if (!i) {
      m0 = pp.pe;
      ans = sols[i];
    } else {
      long long m1 = pp.pe * inv(pp.pe, m0);
      long long m2 = m0 * inv(m0, pp.pe);
      m0 *= pp.pe;
      std::vector<int> _ans;
      _ans.reserve(ans.size() * sols[i].size());
      for (auto x : ans) {
        for (auto y : sols[i]) {
          _ans.push_back((m1 * x + m2 * y) % m0);
        }
      }
      ans.swap(_ans);
    }
  }
  return ans;
}

void solve() {
  int n, m, k;
  std::cin >> n >> m >> k;
  auto ans = kth_roots_mod_m(n, k, m);
  if (ans.empty()) {
    std::cout << 0 << '\n';
    return;
  }
  std::cout << ans.size() << '\n';
  std::sort(ans.begin(), ans.end());
  for (auto x : ans) std::cout << x << ' ';
  std::cout << '\n';
}

int main() {
  int t;
  std::cin >> t;
  for (; t; --t) {
    solve();
  }
}

References and notes

Footnotes

  1. The modulus mm need not be prime. Any primitive k=2ek=2^e-th root of unity modulo mm can be used for a fast number-theoretic transform modulo mm. In practice, however, the required 2e2^e is usually large, which means every prime factor of mm has the form c2e+1c2^e+1. Each such factor is therefore large, and the composite-modulus case is much less common than the prime-modulus case. ↩

  2. By the counting result for primitive roots, the number of λ\lambda-primitive roots is exactly φ(λ(m))\varphi(\lambda(m)), where φ(⋅)\varphi(\cdot) and λ(⋅)\lambda(\cdot) are Euler's and Carmichael's functions. For almost every integer mm, λ(m)/m=exp⁡(−(1+o(1))log⁡log⁡mlog⁡log⁡log⁡m)\lambda(m)/m = \exp(-(1+o(1))\log\log m\log\log\log m), while there is a constant C>0C > 0 such that φ(m)/m=C/log⁡log⁡m\varphi(m)/m = C / \log\log m for m>2m > 2. Hence, for almost every mm, φ(λ(m))/m=exp⁡(−(1+o(1))log⁡log⁡mlog⁡log⁡log⁡m)\varphi(\lambda(m))/m = \exp(-(1+o(1))\log\log m\log\log\log m). The o(1)o(1) term absorbs the contribution from φ(λ(m))/λ(m)\varphi(\lambda(m))/\lambda(m). Thus a λ\lambda-primitive root can be found in expected time exp⁡((1+o(1))log⁡log⁡mlog⁡log⁡log⁡m)\exp((1+o(1))\log\log m\log\log\log m). Estimates for Euler's function can be found in Rosser, J. Barkley, and Lowell Schoenfeld, “Approximate formulas for some functions of prime numbers,” Illinois Journal of Mathematics 6, no. 1 (1962): 64–94. Estimates for Carmichael's function can be found in Erdos, Paul, Carl Pomerance, and Eric Schmutz, “Carmichael’s lambda function,” Acta Arith 58, no. 4 (1991): 363–385. ↩

  3. The original paper is Adleman, Leonard, Kenneth Manders, and Gary Miller, “On taking roots in finite fields,” in 18th Annual Symposium on Foundations of Computer Science (SFCS 1977), pp. 175–178, IEEE Computer Society, 1977. A more readable introduction is Cao, Zhengjun, Qian Sha, and Xiao Fan, “Adleman–Manders–Miller root extraction method revisited,” in International Conference on Information Security and Cryptology, pp. 77–85, Springer, Berlin and Heidelberg, 2011. ↩

  4. This algorithm requires kk to be prime. In the worst case it must find a pp-th root of aa modulo mm, where pp is the largest prime factor of φ(m)\varphi(m). The inputs aa and mm are fixed, and the algorithm must also determine a discrete logarithm of aa modulo mm to a pp-th primitive root of unity; even with BSGS it takes O(p)O(\sqrt{p}) time. Fouvry's paper, “Theoreme de Brun–Titchmarsh; application au theoreme de Fermat,” Inventiones mathematicae 79, no. 2 (1985): 383–407, shows that a positive-density set of primes mm has largest prime factor p=Ω(m2/3)p=\Omega(m^{2/3}) in φ(m)=m−1\varphi(m)=m-1. Thus this algorithm has complexity at least Ω(m1/3)\Omega(m^{1/3}), worse than the improved Tonelli–Shanks algorithm described here. ↩

This content comes from OI Wiki: Higher-Order Residues & Roots of Unity. See the original for authors and revision history. AIOJ has adapted the formatting, in-site links, and resource paths.

Content is shared under CC BY-SA 4.0 and SATA license; additional terms are governed by the original notice. Thanks to the OI Wiki authors and contributors; per the SATA terms, please visit the OI Wiki repository and star it to show your support.