Day 167-Q5 — 2026-10-01 | Carmichael 関数 λ(n) と乗法位数(φ でなく λ から始め、素因数ごとに割って最小にする)

2026-10-01 赤色 Master (Phase 8+) ★★★★★★★★★ 数論(焦点帯 M3)。$n$ を法とする既約剰余類群の指数 $\lambda(n)$(全ての $a$ の位数の最小公倍数)を、素数冪ごとの値の最小公倍数として作り、各 $a$ の位数は $\lambda(n)$ の素因数を 1 つずつ試し割りして最小にする。積を取る誤りと$2^e$ の特別扱いの誤りを数で確かめる 10/1 のバックフィル分(出題日を 2026-10-01 として生成)

問題

正整数 $n$ と $Q$ 個の整数 $a_1,\dots,a_Q$ が与えられる。次を出力せよ。

  • 1 行目: $\lambda(n)$。$n$ と互いに素な全ての $a$ について $a^k\equiv1\pmod n$ となる最小の正整数 $k$($n=1$ のとき 1)。
  • 続く $Q$ 行: $\gcd(a_i,n)=1$ のとき、$a_i$ の $n$ を法とする位数($a_i^k\equiv1\pmod n$ となる最小の正整数 $k$)。$\gcd(a_i,n)\ne1$ のとき $-1$。

入力形式

n Q
a_1
...
a_Q

制約

#条件
1$1\le n\le10^{12}$, $1\le Q\le10^4$
2$1\le a_i\le10^{12}$

入力例1

10 5
3
7
9
1
2

出力例1

4
4
4
2
1
-1

($\lambda(10)=\operatorname{lcm}(\lambda(2),\lambda(5))=\operatorname{lcm}(1,4)=4$。$9\equiv-1$ の位数は 2、$1$ の位数は 1、$\gcd(2,10)=2$ なので $-1$)

入力例2

561 3
2
5
560

出力例2

80
40
80
2

($561=3\cdot11\cdot17$ は最小の Carmichael 数。$\lambda=\operatorname{lcm}(2,10,16)=80$ で、$560=n-1\equiv-1$ の位数は 2)

入力例3

1024 3
3
5
1023

出力例3

256
256
256
2

($\lambda(2^{10})=2^{8}=256$。$\varphi(2^{10})=512$ ではない)

入力例4

1000000007 2
5
2

出力例4

1000000006
1000000006
500000003

(素数 $p$ では $\lambda(p)=p-1$。5 は原始根、2 の位数は $(p-1)/2$)

背景と出典

Carmichael 関数の定義は「$\lambda(p^e)=\varphi(p^e)$($p$ が奇素数、または $p^e\in\{2,4\}$)、$\lambda(2^e)=2^{e-2}$($e\ge3$)、$\lambda(\prod p_i^{e_i})=\operatorname{lcm}\lambda(p_i^{e_i})$」と記憶している。本セッションでは出典を確認していないので、下の検証ログの全探索(位数の最大値との一致)を根拠にする。

$\lambda(n)$ が $\varphi(n)$ より小さくなる $n$ は多く($n\le3000$ のうち 2285 個、実測)、また $n$ が Carmichael 数であることと「$n$ が平方因子を持たない合成数で、各素因数 $p$ について $p-1\mid n-1$」は同値(Korselt の判定法) と記憶している。後者は検証ログで $n\le10^6$ の 43 個を数えて確かめた。

この問題で確かめたいのは次の 3 点。(1) $\lambda(n)$ の式と位数の求め方が、$n\le800$ の全ての $(n,a)$ について全探索と一致するか。(2) $\lambda$ を作る式を誤る 2 通り(積を取る=結果は $\varphi(n)$ になる、$2^2$ を $2^{e-2}$ に含める)が何件で外れるか。(3) $n\approx10^{12}$ で、求めた位数が本当に最小か。

ヒント(クリックで段階的に開示)

ヒント1(方向性)

$a^k\equiv1\pmod n$ は、$n$ の素因数分解の各素数冪 $p^e$ で $a^k\equiv1\pmod{p^e}$ が成り立つことと同値(中国剰余定理)。したがって $k$ の候補は、各素数冪の位数の最小公倍数の倍数。

ヒント2(アプローチ)

全ての $a$ に共通の指数 $\lambda(n)$ をあらかじめ作る。$a$ の位数は $\lambda(n)$ の約数なので、$t=\lambda(n)$ から始め、$t$ の素因数 $q$ ごとに「$a^{t/q}\equiv1$ なら $t\leftarrow t/q$」を割れなくなるまで繰り返す。

ヒント3(誘導)

$\lambda(n)$ は素因数分解のかたち(素数 → 指数)で持つ。各素数冪について $p^{e-1}$ と、$p-1$ の素因数分解を、最大指数を取って混ぜる(最小公倍数)。$p=2$ は $e=1$ で 1、$e=2$ で 2、$e\ge3$ で $2^{e-2}$ と場合分けする。$p-1\le10^{12}$ の素因数分解は $\sqrt{10^{12}}=10^6$ までの試し割りで足りる。$Q$ 回の位数の計算は $\log\lambda$ 個の素因数ごとに pow を呼ぶ。

模範解答 (Python)

模範解答を表示する(まず自力で解いてから)
import sys
from math import gcd
def sieve(L):
    sv = bytearray([1])*(L+1); sv[0]=sv[1]=0
    for i in range(2, int(L**0.5)+1):
        if sv[i]: sv[i*i::i] = bytearray(len(sv[i*i::i]))
    return [i for i in range(L+1) if sv[i]]
PR = sieve(1000000)
def factor(x):
    f = {}
    for p in PR:
        if p*p > x: break
        while x % p == 0:
            f[p] = f.get(p,0)+1; x //= p
    if x > 1: f[x] = f.get(x,0)+1
    return f
def carmichael(fn):
    """λ(n) を素因数分解のかたち {素数: 指数} で返す。fn = n の素因数分解"""
    lam = {}
    def lcm_in(d):
        for q, e in d.items():
            if lam.get(q,0) < e: lam[q] = e
    for p, e in fn.items():
        if p == 2:
            if e == 2: lcm_in({2:1})
            elif e >= 3: lcm_in({2:e-2})
            # e == 1 は λ(2)=1 で何も足さない
        else:
            if e > 1: lcm_in({p:e-1})
            lcm_in(factor(p-1))
    return lam
def order(a, n, lam):
    """gcd(a,n)=1 の a の n を法とする位数。λ(n) から素因数ごとに割っていく"""
    t = 1
    for q, e in lam.items(): t *= q**e
    for q in lam:
        while t % q == 0 and pow(a, t//q, n) == 1 % n: t //= q
    return t
def main():
    data = sys.stdin.read().split()
    n, Q = int(data[0]), int(data[1])
    lam = carmichael(factor(n))
    L = 1
    for q, e in lam.items(): L *= q**e
    print(L)
    for i in range(Q):
        a = int(data[2+i])
        print(order(a, n, lam) if gcd(a, n) == 1 else -1)
if __name__ == "__main__": main()

計算量: 素数の篩 $O(L\log\log L)$($L=10^6$)、$n$ の素因数分解と各 $p-1$ の分解が $O(\pi(L))$ ずつ、位数 1 回あたり(素因数の個数)×$O(\log n)$。実測(Python 3.14.7、M1 Mac)で $n=999999999989$(素数)、$Q=10^4$ が篩を除く本体 0.31 s。

Step-by-Step 解説

1素数冪ごとの λ

$p$ が奇素数なら $(\mathbb Z/p^e)^\times$ は巡回群で位数 $\varphi(p^e)=p^{e-1}(p-1)$、したがって $\lambda(p^e)=p^{e-1}(p-1)$。$p=2$ では $e=1$ が 1、$e=2$ が 2、$e\ge3$ では巡回でなく $\lambda(2^e)=2^{e-2}$。

2最小公倍数で合成する

$\lambda(n)=\operatorname{lcm}_i\lambda(p_i^{e_i})$。素因数分解で持てば、素数ごとに指数の最大を取るだけ。積にすると過大になる($n=15$ で $\lambda=\operatorname{lcm}(2,4)=4$、積だと 8)。

3位数は λ の素因数を割って作る

$a$ の位数は $\lambda(n)$ の約数。$t=\lambda(n)$ から、素因数 $q$ ごとに $a^{t/q}\equiv1$ である限り $t\leftarrow t/q$ とする。どの $q$ でも割れなくなった $t$ が最小。

4n=1 の扱い

$n=1$ では $\lambda(1)=1$、全ての $a$ の位数が 1。pow(a, t, 1) は 0 になるので、比較の右辺を 1 % n(= 0)にしておく。

5Korselt との関係(発展)

合成数 $n$ について「$n$ が平方因子を持たず、$\lambda(n)\mid n-1$」なら、$n$ と互いに素な全ての $a$ で $a^{n-1}\equiv1$(Carmichael 数)。この判定に $\lambda$ をそのまま使える。

迷った他案と採らなかった理由

案計算量採否理由
λ(n) から素因数を割る(本解)位数 1 回あたり $O(\omega(\lambda)\log n)$採用$n\le800$ の全 $(n,a)$ で一致
φ(n) から素因数を割る同じ不採用位数は φ の約数なので正しく出る(理屈のみで、この組み合わせは実測していない)が、$\lambda$ を出力する本問では結局 $\lambda$ が要る。$\varphi$ の素因数は $\lambda$ より多く、pow の回数が増える
位数を 1, 2, 3, … と順に試す$O(\operatorname{ord})$検算用のみ$n\le800$ でしか動かない
素数冪ごとに位数を求めて LCM(CRT 風)$O(\omega\cdot\text{位数})$不採用各素数冪での離散対数的な処理は要らず、$\lambda$ の素因数を割る方が単純

前提が変わったら:

  • $n\le10^{18}$ では $\sqrt n=10^9$ の試し割りが重い。Miller–Rabin と Pollard の rho 法による素因数分解が要る。実装していない
  • 位数でなく離散対数($a^x\equiv b$ を解く)を求める場合は、BSGS や Pohlig–Hellman が要る。位数を求める本解は Pohlig–Hellman の準備段階にあたる
  • $a$ が $n$ と互いに素でない場合の周期(前周期+周期)を問うと、各素数冪ごとの前周期の長さが要る。本解は $-1$ を返すだけ

よくあるミス

ミス原因正しい書き方
素数冪の λ を積で合成する(結果は $\varphi(n)$ そのもの)LCM と積を混同する素因数ごとに指数の最大を取る($n\le3000$ のうち 2285 個で $\lambda\ne\varphi$)
$\lambda(2^e)=\varphi(2^e)$ とする$2^e$ が巡回群でないことを忘れる$e\ge3$ で $2^{e-2}$(この誤りだけの件数は測っていない)
$\lambda(4)$ を 1 にする$2^{e-2}$ を $e=2$ にも使う$e=2$ は 2 を直接返す(外れるのは 3000 個中 $n=4$ の 1 個だが、$a=3$ の位数が 2 のところで確実に誤る)
$n=1$ で比較が通らないpow(a,t,1) は 0 で、== 1 が偽右辺を 1 % n にする
gcd を確かめずに位数を求める$a$ と $n$ が互いに素でないgcd(a,n)==1 でなければ $-1$

次のステップ

  • 発展1: 原始根が存在する $n$($1,2,4,p^e,2p^e$)を $\lambda(n)=\varphi(n)$ で判定し、$n\le10^{12}$ で原始根を 1 つ求める
  • 発展2: Korselt の判定法で、$10^{12}$ 以下の Carmichael 数を $n=p\cdot q\cdot r$ の形(素因数 3 個)に絞って列挙する
  • 次回予告: 焦点帯 M1 から 3 問以上を含む通常のローテーション

検証ログ(本セッションで実行した数値)

  • 全探索との照合(実測): $1\le n\le800$ の全ての $(n,a)$($\gcd(a,n)=1$)で、反復による位数と一致。各 $n$ で位数の最大値が $\lambda(n)$ と一致
  • 誤った式(実測、$n\le3000$ について式の出力同士を比べた。$\lambda$ の式が全探索と一致したのは $n\le800$ まで): 積で合成した値は $\varphi(n)$ と一致し、$\lambda(n)$ と違う $n$ が 2285 個。$2^2$ を $2^{e-2}=1$ とすると $n=4$ の 1 個
  • 最小性の確認(実測): $10^{11}\le n\le10^{12}$ の 40 個の $n$ で、$\gcd(a,n)=1$ の $a$ を 116 個選び、求めた位数 $o$ が $a^o\equiv1$ を満たし、$o$ の各素因数 $q$ で $a^{o/q}\not\equiv1$ になることを確認。$o$ の素因数分解は本解とは別実装の試し割りで行った
  • Korselt の確認(実測): 平方因子なし・合成数・$\lambda(n)\mid n-1$ を満たす $n\le10^6$ は 43 個(先頭は 561, 1105, 1729, 2465, 2821, 6601, 8911, 10585)。先頭 5 個は $\gcd(a,n)=1$ の全ての $a$ で $a^{n-1}\equiv1$ を直接確認。$10^3,10^4,10^5,10^6$ 以下の個数は 1, 7, 16, 43 で、手元の記憶にある Carmichael 数の個数表と一致(出典は未確認)
  • 入力例(実測): 出力例のとおり
  • 実行時間(実測): $n=999999999989$、$Q=10^4$ で 0.31 s(素数の篩を除く)。$n=2^{39}\cdot3$ の $\lambda$ は 137438953472($2^{37}$)
  • 扱っていない範囲: Pollard の rho 法、$n>10^{12}$、離散対数、$\gcd(a,n)\ne1$ の周期、Carmichael 数の個数表の出典の確認

自己評価

自分の回答

気づき・メモ