官方的题解看不懂,问了 S h o n e {\rm Shone} Shone终于听懂了,感觉是一个很神奇的方法,所以就记一下了。
首先题目要求求出 x m ≡ x ( m o d n ) x^m\equiv x({\rm mod\ }n) xm≡x(mod n)的方程的解的个数,其中 x ∈ [ 1 , n ] x\in[1,n] x∈[1,n]。
题目给的 n n n的读入方式很特别,已经在提示你需要将 n n n分解, n n n不一定是质数,但是同余方程在模数为质数的情况下更容易发现特殊性质,所以我们将方程转化为另外一种形式:
令 n = p 1 × p 2 × ⋯ × p c n=p_1\times p_2\times\cdots\times p_c n=p1×p2×⋯×pc,那么有如下转换:
x m ≡ x ( m o d n ) ⇔ { x m ≡ x ( m o d p 1 ) x m ≡ x ( m o d p 2 ) ⋮ x m ≡ x ( m o d p c ) x^m\equiv x({\rm mod\ }n)\Leftrightarrow\begin{cases}x^m\equiv x({\rm mod\ }p_1)\\x^m\equiv x({\rm mod\ }p_2)\\\ \ \ \ \ \ \ \ \ \ \ \vdots\\x^m\equiv x({\rm mod\ }p_c)\end{cases} xm≡x(mod n)⇔⎩⎪⎪⎪⎪⎨⎪⎪⎪⎪⎧xm≡x(mod p1)xm≡x(mod p2) ⋮xm≡x(mod pc)
这个很好理解,甚至感觉很像 C R T CRT CRT,有这个感觉就很对啦。
我们只要知道右面的方程组有多少个不同的解就行了,我们先分开考虑对于每一个方程有多少个满足条件的解,对于 x m ≡ x ( m o d p i ) x^m\equiv x({\rm mod\ }p_i) xm≡x(mod pi),如果令满足条件的 x ( x ∈ [ 0 , p i − 1 ] ) x(x\in[0,p_i-1]) x(x∈[0,pi−1])构成的集合为 U i U_i Ui,那么如果我们从每个方程的解的集合里选一个数 w i w_i wi出来,求出一个 x x x满足所有方程选出来的 w i w_i wi,也就是下面这个方程组:
{ x ≡ w 1 ( m o d p 1 ) x ≡ w 2 ( m o d p 2 ) ⋮ x ≡ w c ( m o d p c ) \begin{cases}x\equiv w_1({\rm mod\ }p_1)\\x\equiv w_2({\rm mod\ }p_2)\\\ \ \ \ \ \ \ \ \ \ \ \vdots\\x\equiv w_c({\rm mod\ }p_c)\end{cases} ⎩⎪⎪⎪⎪⎨⎪⎪⎪⎪⎧x≡w1(mod p1)x≡w2(mod p2) ⋮x≡wc(mod pc)
那么解出来的答案就是一个满足要求的 x x x,如果我们用 C R T CRT CRT求解这个方程组,可以得到一个最小的合法的解 v v v,虽然 v + k n v+kn v+kn都是满足上面方程的,但是由于我们对解的范围有限制,可以发现只有 v v v满足条件,也就是说,一个方程组唯一对应一个解,那么求出有多少不同的方程组,就求出了题目要求的答案。
那么显然,答案就是下面这个公式:
∏ i = 1 c ∣ U i ∣ \prod_{i=1}^c|U_i| i=1∏c∣Ui∣
对于每一个 ∣ U i ∣ |U_i| ∣Ui∣,可以暴力枚举所有可能的解来求出集合大小,那么复杂度是 O ( T c t l o g m ) O(Tct{\rm log}m) O(Tctlogm),算下来感觉不太对,但是卡卡常就能卡过此题。
其实我们有更优秀的算法。
在提交记录里我们发现一份复杂度异常优秀的代码,我们研究了一下发现,对于求解 ∣ U i ∣ |U_i| ∣Ui∣,有一个神奇的公式:
∣ U i ∣ = g c d ( m − 1 , p i − 1 ) + 1 |U_i|={\rm gcd}(m-1,p_i-1)+1 ∣Ui∣=gcd(m−1,pi−1)+1
有了这个公式,复杂度就直接降到了 O ( T c l o g m ) O(Tc{\rm log}m) O(Tclogm),简直是太美妙了。
但是怎么证明?
请教了几位大佬,最终 T i m e t r a v e l l e r {\rm Timetraveller} Timetraveller成功想出证明。
给定 m m m和 p p p,且 p p p为质数:
∑ i = 1 p [ i m ≡ i m o d p ] = g c d ( m − 1 , p − 1 ) + 1 \sum_{i=1}^p[i^m\equiv i{\ \rm mod\ }p]={\rm gcd}(m-1,p-1)+1 i=1∑p[im≡i mod p]=gcd(m−1,p−1)+1
证明:
我们想求出当 x ∈ [ 0 , p − 1 ] x\in[0,p-1] x∈[0,p−1]时, x m ≡ x m o d p x^m\equiv x{\ \rm mod}\ p xm≡x mod p的 x x x的个数,首先考虑 p p p为奇质数的情况,这个时候一定存在一个原根 g g g,根据原根的性质, x x x在 m o d p {\rm mod}\ p mod p的意义下一定可以表示成 g y g^y gy,但是 0 0 0除外,不过因为 0 0 0必定满足上面的方程,所以最后加 1 1 1就行,现在公式就转化成了 g m y ≡ g y m o d p g^{my}\equiv g^y{\ \rm mod}\ p gmy≡gy mod p,根据费马小定理得到 m y ≡ y m o d p − 1 my\equiv y{\ \rm mod}\ p-1 my≡y mod p−1,移项得到 ( m − 1 ) y ≡ 0 m o d p − 1 (m-1)y\equiv 0{\ \rm mod}\ p-1 (m−1)y≡0 mod p−1,两边同时除以 k = g c d ( m − 1 , p − 1 ) k=gcd(m-1,p-1) k=gcd(m−1,p−1)得到 m − 1 k y ≡ 0 m o d p − 1 k \frac{m-1}{k}y\equiv0{\ \rm mod}\ \frac{p-1}{k} km−1y≡0 mod kp−1,由于 g c d ( m − 1 k , p − 1 k ) = 1 gcd(\frac{m-1}{k},\frac{p-1}{k})=1 gcd(km−1,kp−1)=1,则 y y y必定是 p − 1 k \frac{p-1}{k} kp−1的倍数,可以知道 p − 1 k \frac{p-1}{k} kp−1的 0 ∼ k − 1 0\thicksim k-1 0∼k−1倍都是合法的 y y y,大于 k − 1 k-1 k−1倍的都是重复的,所以有 k k k个不同的 y y y满足条件,之前说过还有 0 0 0没计算,所以答案为 k + 1 k+1 k+1个。
上面之所以说奇质数,是因为 2 2 2没有原根,上面的证明用到了原根,但是实际上 2 2 2也满足那些有原根的数的性质,所以证明依然成立。