1. 程式人生 > >洛谷比賽【泯滅:整除】

洛谷比賽【泯滅:整除】

題目連結

官方的題解看不懂,問了Shone{\rm Shone}終於聽懂了,感覺是一個很神奇的方法,所以就記一下了。

首先題目要求求出xmx(modn)x^m\equiv x({\rm mod\ }n)的方程的解的個數,其中x[1,n]x\in[1,n]

題目給的nn的讀入方式很特別,已經在提示你需要將nn分解,並且nn不是質數,但是同餘方程在模數為質數的情況下更容易發現特殊性質,所以我們將方程轉化為另外一種形式:

n=p1×p2××pcn=p_1\times p_2\times\cdots\times p_c

pc,那麼有如下轉換:

xmx(modn){xmx(modp1)xmx(modp2)xmx(modpc)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}

這個很好理解,甚至感覺很像C

RTCRT,有這個感覺就很對啦。

我們只要知道右面的方程組有多少個不同的解就行了,我們先分開考慮對於每一個方程有多少個滿足條件的解,對於xmx(modpi)x^m\equiv x({\rm mod\ }p_i),如果令滿足條件的x(x[0,pi1])x(x\in[0,p_i-1])構成的集合為UiU_i,那麼如果我們從每個方程的解的集合裡選一個數wiw_i出來,求出一個xx滿足所有方程選出來的wiw_i,也就是下面這個方程組:

{xw1(modp1)xw2(modp2)xwc(modpc)\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}

那麼解出來的答案就是滿足要求的xx,如果我們用CRTCRT求解這個方程組,可以得到一個最小的合法的解vv,雖然v+knv+kn都是滿足上面方程的,但是由於我們對解的範圍有限制,可以發現只有vv滿足條件,也就是說,一個方程組唯一對應一個解,那麼求出有多少不同的方程組,就求出了題目要求的答案。

那麼顯然,答案就是下面這個公式:

i=1cUi\prod_{i=1}^c|U_i|

對於每一個Ui|U_i|,可以暴力列舉所有可能的解來求出集合大小,那麼複雜度是O(Tctlogm)O(Tct{\rm log}m),算下來感覺不太對,但是卡卡常就能卡過此題。

其實我們有更優秀的演算法。

在提交記錄裡我們發現一份複雜度異常優秀的程式碼,我們研究了一下發現,對於求解Ui|U_i|,有一個神奇的公式:

Ui=gcd(m1,pi1)+1|U_i|={\rm gcd}(m-1,p_i-1)+1

有了這個公式,複雜度就直接降到了O(Tclogm)O(Tc{\rm log}m),簡直是太美妙了。

但是怎麼證明?

給定mmpp,且pp為質數:

i=1p[imimodp]=gcd(m1,p1)+1\sum_{i=1}^p[i^m\equiv i{\ \rm mod\ }p]={\rm gcd}(m-1,p-1)+1

證明:

我們想求出當x[0,p1]x\in[0,p-1]時,xmxmodpx^m\equiv x{\ \rm mod}\ pxx的個數,首先考慮pp為奇質數的情況,這個時候一定存在一個原根gg,根據原根的性質,xxmodp{\rm mod}\ p的意義下一定可以表示成gyg^y,但是00除外,不過因為00必定滿足上面的方程,所以最後加11就行,現在公式就轉化成了gmygymodpg^{my}\equiv g^y{\ \rm mod}\ p,根據費馬小定理得到myymodp1my\equiv y{\ \rm mod}\ p-1,移項得到(m1)y0modp1(m-1)y\equiv 0{\ \rm mod}\ p-1,兩邊同時除以k=gcd(m1,p1)k=gcd(m-1,p-1)得到m1ky0modp1k\frac{m-1}{k}y\equiv0{\ \rm mod}\ \frac{p-1}{k},由於gcd(m1k,p1k)=1gcd(\frac{m-1}{k},\frac{p-1}{k})=1,則yy必定是p1k\frac{p-1}{k}的倍數,可以知道p1k\frac{p-1}{k}0k10\thicksim k-1倍都是合法的yy,大於k1k-1倍的都是重複的,所以有kk個不同的yy滿足條件,之前說過還有00沒計算,所以答案為k+1k+1個。

上面之所以說奇質數,是因為22沒有原根,上面的證明用到了原根,但是實際上22也滿足那些有原根的數的性質,所以證明依然成立。

關於原根,還是之前學NTT\rm NTT的時候瞭解的,沒想到還能用在這個的證明上面,但是對於同餘方程這些和剩餘繫有關的東西,當實在沒有思路的時候,確實應該往原根上想一想,尤其是模數為質數的時候。