1. 程式人生 > >【洛谷題解】P2303 [SDOi2012]Longge的問題

【洛谷題解】P2303 [SDOi2012]Longge的問題

情況 .org 得到 因數分解 n) nbsp 自己 tro 如果

題目傳送門:鏈接。

能自己推出正確的式子的感覺真的很好!

題意簡述:

求\(\sum_{i=1}^{n}gcd(i,n)\)。\(n\leq 2^{32}\)。

題解:

我們開始化簡式子:

\(\sum_{i=1}^{n}gcd(i,n)\)

\(=\sum_{j=1}^{n}\left(j\times\sum_{i=1}^{n}\left[gcd(i,n)=j\right]\right)\)

\(=\sum_{j=1}^{n}\left(j\times\sum_{i=1}^{n}\left[gcd(i/j,n/j)=1\right]\left(j|i,j|n\right)\right)\)

\(=\sum_{j=1}^{n}\left(j\times\varphi\left(n/j\right)\left(j|n\right)\right)\)

\(=\sum_{j|n}\left(j\times\varphi\left(n/j\right)\right)\)

到這裏就可以直接計算了。

但是還可以進一步化簡!(以下的\(p\)為質數)

\(\sum_{j|n}(j\times\varphi(n/j))\)

\(=\sum_{j|n}(n/j\times\varphi\left(j\right))\)

\(=\sum_{j|n}(n/j\times(j\cdot\prod_{p|j}\frac{p-1}{p}))\)

\(=\sum_{j|n}(n\cdot\prod_{p|j}\frac{p-1}{p})\)

\(=n\times\sum_{j|n}\prod_{p|j}\frac{p-1}{p}\)

接下來我們令\(n=p_1^{b_1}p_2^{b_2}p_3^{b_3}\cdots p_k^{b_k}\),並定義\(f_i=\frac{p_i-1}{p_i}\)。

那麽\(n\)的因子\(j\)可以表示為:\(j=p_1^{c_1}p_2^{c_2}p_3^{c_3}\cdots p_k^{c_k}\),滿足\(0\leq c_i\leq b_i\)。

那麽\(\prod_{p|j}\frac{p-1}{p}=\prod_{i=1}^kf_i[c_i>0]\)。

我們觀察一類\(\prod_{i=1}^kf_i[c_i>0]\)相等的\(j\),它們必要滿足在\(i\)相等的情況下,\(c_i\)同時大於0或\(c_i\)同時等於0。

那麽這一類的\(j\)有多少個呢?如果這類\(j\)有質因子\(p_{q_1},p_{q_2},p_{q_3},\cdots,p_{q_g}\)。

那麽這類\(j\)的答案為\(\prod_{i=1}^gf_{q_i}\),而個數為\(\prod_{i=1}^gb_{q_i}\)。

\(b_i\)就是原來\(n\)的質因數分解的指數。

那麽對答案的貢獻為:\(\prod_{i=1}^g\chi_{q_i}\)。這裏\(\chi_i=f_i\cdot b_i\)。

發現每一個質因子的貢獻都是獨立的,那麽最後我們枚舉\(n\)的每一個質因子取不取,得到最後的答案:\(n\cdot\prod_{i=1}^{k}(\chi_i+1)\)。

舉個例子:如果\(n\)只有\(3\)個質因子,那麽答案為\(n\cdot(1+\chi_1+\chi_2+\chi_3+\chi_1\chi_2+\chi_1\chi_3+\chi_2\chi_3+\chi_1\chi_2\chi_3)\)。

顯然可以化簡為:\(n\cdot(\chi_1+1)\cdot(\chi_2+1)\cdot(\chi_3+1)\)。

當然可以類比到質因數更多的情況。

總之,答案就是:\(n\cdot\prod_{i=1}^{k}\frac{b_i\cdot p_i-b_i+p_i}{p_i}\)。

代碼:

 1 #include<cstdio>
 2 long long n;
 3 long long f(){
 4     long long ans=n; long long i;
 5     for(i=2;i*i<=n;++i) if(n%i==0){
 6         int b=0;
 7         while(n%i==0) ++b,n/=i;
 8         ans/=i;
 9         ans*=b*i-b+i;
10     } if(n>1) ans/=n, ans*=n+n-1; 
11     return ans;
12 }
13 int main(){
14     scanf("%lld",&n);
15     printf("%lld",f());
16     return 0;
17 }

【洛谷題解】P2303 [SDOi2012]Longge的問題