數論千萬條,反演第一條。反演不會做,隊友兩行淚。
一、什麼是莫比烏斯反演?
g ( n ) = ∑ d ∣ n f ( d ) ⟺ f ( n ) = ∑ d ∣ n μ ( d ) g ( n d ) . . . . . . . . . . . . . ( 1 ) {g(n) = \displaystyle\sum_{d|n}f(d)\Longleftrightarrow f(n) = \displaystyle\sum_{d|n}\mu(d)g(\frac{n}{d})}.............(1) g ( n ) = d ∣ n ∑ f ( d ) ⟺ f ( n ) = d ∣ n ∑ μ ( d ) g ( d n ) . . . . . . . . . . . . . ( 1 )
g ( n ) = ∑ n ∣ d f ( d ) ⟺ f ( n ) = ∑ n ∣ d μ ( d n ) g ( d ) . . . . . . . . . . . . . . ( 2 ) {g(n) = \displaystyle\sum_{n|d}f(d)\Longleftrightarrow f(n) = \displaystyle\sum_{n|d}\mu(\frac{d}{n})g(d)}..............(2) g ( n ) = n ∣ d ∑ f ( d ) ⟺ f ( n ) = n ∣ d ∑ μ ( n d ) g ( d ) . . . . . . . . . . . . . . ( 2 )
很多時候函數f f f 很難求,但是函數g g g 可以比較容易的求出來,所有我們通過求出g g g 來求出f f f ,這個由g g g 求出f f f 的過程就是反演。
二、前置知識
1.莫比烏斯函數
μ ( n ) = { 1 , n = 1 ( − 1 ) k , n = P 1 P 2 . . . P k 0 , o t h e r \mu(n) =\begin{cases} 1,\ \ \ \ \ \ \ \ \ \ n=1\\ (-1)^k,\ \ n = P_1P_2...P_k\\0,\ \ \ \ \ \ \ \ \ \ other\end{cases} μ ( n ) = ⎩ ⎪ ⎨ ⎪ ⎧ 1 , n = 1 ( − 1 ) k , n = P 1 P 2 . . . P k 0 , o t h e r
其中P 1 P 2 . . . P k P_1P_2...P_k P 1 P 2 . . . P k 爲質數。
莫比烏斯函數推導
線性篩求莫比烏斯函數:
int prime_tot = 0 ;
bool prime_tag[ N] ;
int prime[ N] , mu[ N] ;
void get_prime ( ) {
mu[ 1 ] = 1 ;
for ( int i = 2 ; i < N; i++ ) {
if ( ! prime_tag[ i] ) prime[ prime_tot++ ] = i, mu[ i] = - 1 ;
for ( int j = 0 ; j < prime_tot && i * prime[ j] < N; j++ ) {
prime_tag[ i * prime[ j] ] = true ;
if ( i % prime[ j] == 0 ) {
mu[ i * prime[ j] ] = 0 ;
break ;
} else
mu[ i * prime[ j] ] = - mu[ i] ;
}
}
}
2.狄利克雷卷積
狄利克雷卷積是一個對函數的運算。
狄利克雷卷積:
對於兩個函數f , g f,g f , g ,它們的狄利克雷卷積是
( f ∗ g ) ( n ) = ∑ d ∣ n f ( d ) g ( n d ) (f*g)(n) = \displaystyle\sum_{d|n}f(d)g(\frac{n}{d}) ( f ∗ g ) ( n ) = d ∣ n ∑ f ( d ) g ( d n )
積性函數:
兩個數a , b a,b a , b 互質,對於函數f f f ,如果f ( a b ) = f ( a ) f ( b ) f(ab)=f(a)f(b) f ( a b ) = f ( a ) f ( b ) ,那麼函數f f f 就是一個積性函數。
完全積性函數:
任意兩個數a , b a,b a , b ,都有f ( a b ) = f ( a ) f ( b ) f(ab)=f(a)f(b) f ( a b ) = f ( a ) f ( b ) 。
常見的積性函數
歐拉函數φ ( n ) \varphi(n) φ ( n )
莫比烏斯函數μ ( n ) \mu(n) μ ( n )
單位函數 I d ( n ) = n Id(n) = n I d ( n ) = n
不變函數1 ( n ) = 1 1(n) = 1 1 ( n ) = 1 ,不變的函數,所有值都是1 1 1
冪函數i d k ( k ) = n k idk(k) = n^k i d k ( k ) = n k
因子個數函數d ( n ) , d = 1 ( n ) ∗ 1 ( n ) d(n),d = 1(n)*1(n) d ( n ) , d = 1 ( n ) ∗ 1 ( n ) ,n的正因子數目
因子和函數σ ( n ) , σ = 1 ( n ) ∗ I d , n \sigma(n),\sigma = 1(n)*Id,n σ ( n ) , σ = 1 ( n ) ∗ I d , n 的所有正因子之和
因子函數σ k ( n ) σk(n) σ k ( n ) ,n的所有正因子的k次冪之和
狄利克雷卷積單位元ε = [ n = = 1 ] \varepsilon = [n==1] ε = [ n = = 1 ]
逆元 :對於每一個f ( 1 ) = 0̸ f(1)=\not0 f ( 1 ) = 0 的函數f f f ,都有f ∗ g = ε f∗g=\varepsilon f ∗ g = ε
如何求一個函數的逆元:
首先我們定義兩個函數f , g f,g f , g :
g ( n ) = 1 f ( 1 ) ( [ n = = 1 ] − ∑ i ∣ n , i ≠ 1 f ( i ) g ( n i ) ) g(n)=\frac{1}{f(1)}\left([n==1]-\sum_{i|n,i\neq 1}f(i)g(\frac{n}{i})\right) g ( n ) = f ( 1 ) 1 ⎝ ⎛ [ n = = 1 ] − i ∣ n , i = 1 ∑ f ( i ) g ( i n ) ⎠ ⎞
這樣的話,他們的狄利克雷卷積 f ∗ g f*g f ∗ g 就是:
∑ i ∣ n f ( i ) g ( n i ) = f ( 1 ) g ( n ) + ∑ i ∣ n , i ≠ 1 f ( i ) g ( n i ) = f ( 1 ) ∗ 1 f ( 1 ) ( [ n = = 1 ] − ∑ i ∣ n , i ≠ 1 f ( i ) g ( n i ) ) + ∑ i ∣ n , i ≠ 1 f ( i ) g ( n i ) = [ n = = 1 ] \sum_{i|n}f(i)g(\frac{n}{i})\\\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =f(1)g(n)+\sum_{i|n,i\neq1}f(i)g(\frac{n}{i})\\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =f(1)*\frac{1}{f(1)}\left([n==1]-\sum_{i|n,i\neq 1}f(i)g(\frac{n}{i})\right)+ \sum_{i|n,i\neq1}f(i)g(\frac{n}{i})\\=[n==1] i ∣ n ∑ f ( i ) g ( i n ) = f ( 1 ) g ( n ) + i ∣ n , i = 1 ∑ f ( i ) g ( i n ) = f ( 1 ) ∗ f ( 1 ) 1 ⎝ ⎛ [ n = = 1 ] − i ∣ n , i = 1 ∑ f ( i ) g ( i n ) ⎠ ⎞ + i ∣ n , i = 1 ∑ f ( i ) g ( i n ) = [ n = = 1 ]
此處證明推導均來自:鈴懸dalao的博客
一些關於莫比烏斯函數和狄利克雷卷積單位元的性質
1.不變常數 1 1 1 和莫比烏斯函數 μ \mu μ 互爲逆元。
用上述求逆元的方法直接套,令g ( n ) = 1 ( n ) , f ( n ) = μ ( n ) g(n) = 1(n),f(n) = \mu(n) g ( n ) = 1 ( n ) , f ( n ) = μ ( n ) 。
2.兩個積性函數的狄利克雷卷積是積性函數。
3.積性函數的逆是積性函數。
2和3具體詳細的證明還是參考鈴懸dalao的博客https://www.luogu.org/blog/lx-2003/mobius-inversion
3.整除分塊
看一個題目:求∑ k = 1 n ⌊ n k ⌋ \displaystyle\sum^{n}_{k= 1}\lfloor\frac{n}{k}\rfloor k = 1 ∑ n ⌊ k n ⌋ 的值。
可能會想到暴力,直接遍歷一遍,但當n n n 很大的時候,時間是使dalao們不滿意的。
所以有了整除分塊的想法。
拿 n = 25 n = 25 n = 2 5 來舉例:
首先可以發現, ⌊ n k ⌋ \lfloor \frac{\ n\ }{\ k\ }\rfloor ⌊ k n ⌋ 只有2 n 2\sqrt{n} 2 n 種,那我們按照 ⌊ n k ⌋ \lfloor \frac{\ n\ }{\ k\ }\rfloor ⌊ k n ⌋ 的結果分類的:
int ans = 0 ;
for ( int l = 1 , r; l <= n; l = r + 1 ) {
r = n / ( n / l) ;
ans + = ( r - l + 1 ) ( n / l) ;
}
這樣一來,整除通過這種分塊的思想就把時間複雜度降到了O ( 2 n ) O(2\sqrt{n}) O ( 2 n ) 。
三、莫比烏斯反演的證明
g ( n ) = ∑ d ∣ n f ( d ) ⟺ f ( n ) = ∑ d ∣ n μ ( d ) g ( n d ) . . . . . . . . . . . . . ( 1 ) {g(n) = \displaystyle\sum_{d|n}f(d)\Longleftrightarrow f(n) = \displaystyle\sum_{d|n}\mu(d)g(\frac{n}{d})}.............(1) g ( n ) = d ∣ n ∑ f ( d ) ⟺ f ( n ) = d ∣ n ∑ μ ( d ) g ( d n ) . . . . . . . . . . . . . ( 1 )
g ( n ) = ∑ n ∣ d f ( d ) ⟺ f ( n ) = ∑ n ∣ d μ ( d n ) g ( d ) . . . . . . . . . . . . . . ( 2 ) {g(n) = \displaystyle\sum_{n|d}f(d)\Longleftrightarrow f(n) = \displaystyle\sum_{n|d}\mu(\frac{d}{n})g(d)}..............(2) g ( n ) = n ∣ d ∑ f ( d ) ⟺ f ( n ) = n ∣ d ∑ μ ( n d ) g ( d ) . . . . . . . . . . . . . . ( 2 )
首先證明( 1 ) (1) ( 1 ) ,這很好證明(1 1 1 代表不變函數):
g = f ∗ 1 , f = μ ∗ g = μ ∗ 1 ∗ f = f g = f*1,f = \mu*g=\mu *1*f=f g = f ∗ 1 , f = μ ∗ g = μ ∗ 1 ∗ f = f
然後證明( 2 ) (2) ( 2 ) :
令k = d n k = \frac{d}{n} k = n d ,則:
∑ n ∣ d μ ( d n ) g ( d ) = ∑ k μ ( k ) g ( n k ) = ∑ k μ ( k ) ∑ ( n k ) ∣ t f ( t ) \sum_{n|d}\mu(\frac{d}{n})g(d)=\sum_{k}\mu(k)g(nk)=\sum_{k}\mu(k)\sum_{(nk)|t}f(t) n ∣ d ∑ μ ( n d ) g ( d ) = k ∑ μ ( k ) g ( n k ) = k ∑ μ ( k ) ( n k ) ∣ t ∑ f ( t )
∑ t f ( t ) ∑ ( n k ) ∣ t μ ( k ) = ∑ t f ( t ) ε ( t n ) = f ( n ) {\displaystyle \sum_{t}f(t)\sum_{(nk)|t}\mu(k)=\sum_{t}f(t)\varepsilon(\frac{t}{n})=f(n)} t ∑ f ( t ) ( n k ) ∣ t ∑ μ ( k ) = t ∑ f ( t ) ε ( n t ) = f ( n )
四、一點點題目
注:所有例題中g c d ( x , y ) gcd(x,y) g c d ( x , y ) 都爲x , y x,y x , y 的最大公約數。
【例1】luogu P2522 [HAOI2011]Problem b
題意
對於給定的T T T 個詢問,每次求友多少個數對( x , y ) (x,y) ( x , y ) 滿足a ≤ x ≤ b , c ≤ y ≤ d a\leq x\leq b,c\leq y\leq d a ≤ x ≤ b , c ≤ y ≤ d ,且g c d ( x , y ) = k gcd(x,y) = k g c d ( x , y ) = k 。
思路
首先可以將問題使用容斥原理轉化一下:
定義s o l v e ( b , d ) solve(b,d) s o l v e ( b , d ) 爲數對( x , y ) (x,y) ( x , y ) 是滿足1 ≤ x ≤ b , 1 ≤ y ≤ d 1\leq x\leq b,1\leq y\leq d 1 ≤ x ≤ b , 1 ≤ y ≤ d ,且g c d ( x , y ) = k gcd(x,y)=k g c d ( x , y ) = k 的個數。
根據容斥原理:
a n s = s o l v e ( b , d ) − s o l v e ( a − 1 , d ) − s o l v e ( b , c − 1 ) + s o l v e ( a − 1 , c − 1 ) ans = solve(b,d) - solve(a-1,d) - solve(b,c-1) + solve(a-1,c-1) a n s = s o l v e ( b , d ) − s o l v e ( a − 1 , d ) − s o l v e ( b , c − 1 ) + s o l v e ( a − 1 , c − 1 )
這樣就可以利用一種類似於前綴和的方法求出來答案。
問題就轉化爲求出1 ≤ x ≤ ⌊ b k ⌋ , 1 ≤ y ≤ ⌊ d k ⌋ 1\leq x\leq \lfloor\frac{b}{k}\rfloor,1\leq y\leq \lfloor\frac{d}{k}\rfloor 1 ≤ x ≤ ⌊ k b ⌋ , 1 ≤ y ≤ ⌊ k d ⌋ ,且g c d ( x , y ) = 1 gcd(x,y)=1 g c d ( x , y ) = 1 的數對個數。
下面利用莫比烏斯反演,來解題:
首先設
f ( i ) = ∑ x = 1 n ∑ y = 1 m [ g c d ( x , y ) = = i ] f(i) = \displaystyle\sum_{x=1}^{n}\sum_{y=1}^{m}[gcd(x,y) == i] f ( i ) = x = 1 ∑ n y = 1 ∑ m [ g c d ( x , y ) = = i ]
g ( i ) = ∑ x = 1 n ∑ y = 1 m [ i ∣ g c d ( x , y ) ] = ⌊ n i ⌋ ⌊ m i ⌋ g(i) = \displaystyle\sum_{x=1}^{n}\sum_{y = 1}^{m}[i\ |\ gcd(x,y)]=\lfloor\frac{n}{i}\rfloor\lfloor\frac{m}{i}\rfloor g ( i ) = x = 1 ∑ n y = 1 ∑ m [ i ∣ g c d ( x , y ) ] = ⌊ i n ⌋ ⌊ i m ⌋
f ( i ) = ∑ i ∣ q μ ( q i ) g ( q ) = ∑ i ∣ q μ ( q i ) ⌊ n q ⌋ ⌊ m q ⌋ f(i) = \displaystyle\sum_{i|q }\mu(\frac{q}{i})g(q)= \displaystyle\sum_{i|q }\mu(\frac{q}{i})\lfloor\frac{n}{q}\rfloor\lfloor\frac{m}{q}\rfloor f ( i ) = i ∣ q ∑ μ ( i q ) g ( q ) = i ∣ q ∑ μ ( i q ) ⌊ q n ⌋ ⌊ q m ⌋
通過之前推導出的紅字,可以知道現在需要的就是求出f ( 1 ) f(1) f ( 1 ) ,將i = 1 , n = ⌊ b k ⌋ , m = ⌊ d k ⌋ i = 1,n = \lfloor\frac{b}{k}\rfloor,m= \lfloor\frac{d}{k}\rfloor i = 1 , n = ⌊ k b ⌋ , m = ⌊ k d ⌋ 代入,可以得到:
f ( 1 ) = ∑ 1 ∣ q μ ( q 1 ) g ( q ) = ∑ 1 ∣ q μ ( q 1 ) ⌊ b q k ⌋ ⌊ d q k ⌋ f(1) = \displaystyle\sum_{1|q }\mu(\frac{q}{1})g(q)= \displaystyle\sum_{1|q }\mu(\frac{q}{1})\lfloor\frac{b}{qk}\rfloor\lfloor\frac{d}{qk}\rfloor f ( 1 ) = 1 ∣ q ∑ μ ( 1 q ) g ( q ) = 1 ∣ q ∑ μ ( 1 q ) ⌊ q k b ⌋ ⌊ q k d ⌋
然後使用分塊處理可得到答案。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <cctype>
#define ll long long
using namespace std;
const int N = 5e4 + 10 ;
bool prime_tag[ N] = { 0 } ;
int prime[ N] , mu[ N] , prime_tot = 0 ;
ll sum[ N] = { 0 } ;
int cas, a, b, c, d, k;
void get_mu ( ) {
mu[ 1 ] = 1 ;
for ( int i = 2 ; i < N; i++ ) {
if ( ! prime_tag[ i] ) {
prime[ prime_tot++ ] = i;
mu[ i] = - 1 ;
}
for ( int j = 0 ; j < prime_tot && i * prime[ j] < N; j++ ) {
prime_tag[ i * prime[ j] ] = true ;
if ( i % prime[ j] == 0 ) {
mu[ i * prime[ j] ] = 0 ;
break ;
} else {
mu[ i * prime[ j] ] = - mu[ i] ;
}
}
}
sum[ 0 ] = 0 ;
for ( int i = 1 ; i < N; i++ )
sum[ i] = sum[ i - 1 ] + mu[ i] ;
}
ll solve ( ll b , ll d) {
b = b / k;
d = d / k;
ll res = 0 ;
int t = min ( b, d) ;
for ( int l = 1 , r; l <= t; l = r + 1 ) {
r = min ( ( ll) b / ( b / l) , ( ll) d / ( d / l) ) ;
res + = ( sum[ r] - sum[ l - 1 ] ) * ( b / l ) * ( d / l) ;
}
return res;
}
int main ( ) {
get_mu ( ) ;
scanf ( "%d" , & cas) ;
while ( cas-- ) {
scanf ( "%d %d %d %d %d" , & a, & b, & c, & d, & k) ;
printf ( "%lld\n" , solve ( b, d) - solve ( a- 1 , d) - solve ( b, c- 1 ) + solve ( a- 1 , c- 1 ) ) ;
}
return 0 ;
}
【例2】luogu P2257 YY的GCD
題意
給定N , M N,M N , M ,求1 ≤ x ≤ N , 1 ≤ y ≤ M 1\leq x \leq N,1\leq y \leq M 1 ≤ x ≤ N , 1 ≤ y ≤ M 且g c d ( x , y ) gcd(x,y) g c d ( x , y ) 爲質數的( x , y ) (x,y) ( x , y ) 有多少對?
思路
和上一題很像,區別在於要確保g c d ( x , y ) = = k , k gcd(x,y) == k,k g c d ( x , y ) = = k , k 是一個質數。
f ( x ) = ∑ x ∈ p r i m e ∑ x ∣ d μ ( d x ) g ( d ) f(x) = \displaystyle\sum_{x\in prime}\sum_{x\ | \ d}\mu(\frac{d}{x})g(d) f ( x ) = x ∈ p r i m e ∑ x ∣ d ∑ μ ( x d ) g ( d )
= ∑ d = 1 m i n ( n , m ) ⌊ n d ⌋ ⌊ m d ⌋ ∑ x ∈ p r i m e , x ∣ d μ ( d x ) \ \ \ \ \ \ \ \ \ =\displaystyle\sum_{d = 1}^{min(n,m)}\lfloor\frac{n}{d}\rfloor\lfloor\frac{m}{d}\rfloor\sum_{x\in prime ,x\ |\ d}\mu(\frac{d}{x}) = d = 1 ∑ m i n ( n , m ) ⌊ d n ⌋ ⌊ d m ⌋ x ∈ p r i m e , x ∣ d ∑ μ ( x d )
這裏我們可以令:
s u m [ d ] = ∑ x ∈ p r i m e , x ∣ d μ ( d x ) sum[d] = \displaystyle\sum_{x\in prime ,x\ |\ d}\mu(\frac{d}{x}) s u m [ d ] = x ∈ p r i m e , x ∣ d ∑ μ ( x d ) 。
這樣一來:
f ( x ) = ∑ x ∈ p r i m e ∑ x ∣ d μ ( d x ) g ( d ) f(x) = \displaystyle\sum_{x\in prime}\sum_{x\ | \ d}\mu(\frac{d}{x})g(d) f ( x ) = x ∈ p r i m e ∑ x ∣ d ∑ μ ( x d ) g ( d )
= ∑ d = 1 m i n ( n , m ) ⌊ n d ⌋ ⌊ m d ⌋ s u m [ d ] \ \ \ \ \ \ \ \ \ =\displaystyle\sum_{d = 1}^{min(n,m)}\lfloor\frac{n}{d}\rfloor\lfloor\frac{m}{d}\rfloor sum[d] = d = 1 ∑ m i n ( n , m ) ⌊ d n ⌋ ⌊ d m ⌋ s u m [ d ]
預處理代碼:
sum[ 0 ] = 0 ;
for ( int i = 0 ; i < prime_tot; i++ ) {
for ( int j = 1 ; prime[ i] * j < N; j++ ) {
sum[ prime[ i] * j] + = mu[ j] ;
}
}
for ( int i = 1 ; i < N; i++ )
sum[ i] + = sum[ i- 1 ] + sum[ i] ;
提前預處理這個s u m ( d ) sum(d) s u m ( d ) ,再求一個前綴和就可以很好的放在分塊中解決
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#define ll long long
using namespace std;
const int N = 1e7 + 7 ;
int prime[ N] , prime_tot = 0 , mu[ N] ;
ll sum[ N] = { 0 } ;
bool prime_tag[ N] = { 0 } ;
int cas, n, m;
void get_mu ( ) {
mu[ 1 ] = 1 ;
for ( int i = 2 ; i < N; i++ ) {
if ( ! prime_tag[ i] ) {
prime[ prime_tot++ ] = i;
mu[ i] = - 1 ;
}
for ( int j = 0 ; j < prime_tot && i * prime[ j] < N; j++ ) {
prime_tag[ i * prime[ j] ] = true ;
if ( i % prime[ j] == 0 ) {
mu[ i * prime[ j] ] = 0 ;
break ;
}
mu[ i * prime[ j] ] = - mu[ i] ;
}
}
sum[ 0 ] = 0 ;
for ( int i = 0 ; i < prime_tot; i++ ) {
for ( int j = 1 ; prime[ i] * j < N; j++ ) {
sum[ prime[ i] * j] + = mu[ j] ;
}
}
for ( int i = 1 ; i < N; i++ )
sum[ i] + = sum[ i- 1 ] + sum[ i] ;
}
ll solve ( ) {
ll res = 0 , res1 = 0 ;
for ( int l = 1 , r; l <= n; l = r + 1 ) {
r = min ( n / ( n / l) , m / ( m / l) ) ;
res + = ( ll) ( sum[ r] - sum[ l - 1 ] ) * ( n / l) * ( m / l) ;
}
return res / 2 ;
}
int main ( ) {
get_mu ( ) ;
scanf ( "%d" , & cas) ;
while ( cas-- ) {
scanf ( "%d %d" , & n, & m) ;
if ( n > m) swap ( n, m) ;
printf ( "%lld\n" , solve ( ) ) ;
}
return 0 ;
}
【例3】luogu P4449 於神之怒加強版
題意
給定n , m , k n,m,k n , m , k ,計算∑ i = 1 n ∑ j = 1 m g c d ( i , j ) k m o d ( 1 0 9 + 7 ) \displaystyle\sum_{i = 1}^{n}\sum_{j = 1}^{m}gcd(i,j)^k\ mod(10^9+7) i = 1 ∑ n j = 1 ∑ m g c d ( i , j ) k m o d ( 1 0 9 + 7 ) 的值。
思路
枚舉最大公因數 d d d ,並計算最大公因數爲 d d d 的數對個數∑ i = 1 n ∑ j = 1 m [ g c d ( i , j ) = = d ] \displaystyle\sum_{i = 1}^{n}\sum_{j = 1}^{m}[gcd(i,j)==d] i = 1 ∑ n j = 1 ∑ m [ g c d ( i , j ) = = d ] 的值
那麼答案就是 ∑ d m i n ( n , m ) 最 大 公 因 數 爲 d 的 數 對 個 數 × d k \displaystyle\sum_d^{min(n,m)}最大公因數爲 d的數對個數\times d^k d ∑ m i n ( n , m ) 最 大 公 因 數 爲 d 的 數 對 個 數 × d k
我們使用莫比烏斯反演:
設f ( u ) = ∑ i = 1 n ∑ j = 1 m [ g c d ( i , j ) = = u ] . . . . . . . . ( 1 ) g ( u ) = ∑ i = 1 n ∑ j = 1 m [ u ∣ g c d ( i , j ) ] = ⌊ n u ⌋ ⌊ m u ⌋ . . . . . . . . ( 2 ) f(u) = \displaystyle\sum_{i = 1}^{n}\sum_{j = 1}^{m}[gcd(i,j)==u]........(1)
\\g(u) = \displaystyle\sum_{i = 1}^{n}\sum_{j = 1}^{m}[u|gcd(i,j)] = \lfloor\frac{n}{u}\rfloor\lfloor\frac{m}{u}\rfloor........(2) f ( u ) = i = 1 ∑ n j = 1 ∑ m [ g c d ( i , j ) = = u ] . . . . . . . . ( 1 ) g ( u ) = i = 1 ∑ n j = 1 ∑ m [ u ∣ g c d ( i , j ) ] = ⌊ u n ⌋ ⌊ u m ⌋ . . . . . . . . ( 2 )
f ( u ) = ∑ u ∣ p μ ( p u ) g ( p ) f(u) = \displaystyle\sum_{u|p}\mu(\frac{p}{u})g(p) f ( u ) = u ∣ p ∑ μ ( u p ) g ( p )
由於
∑ i = 1 n ∑ j = 1 m [ g c d ( i , j ) = = d ] \displaystyle\sum_{i = 1}^{n}\sum_{j = 1}^{m}[gcd(i,j)==d] i = 1 ∑ n j = 1 ∑ m [ g c d ( i , j ) = = d ] 和 ∑ i = 1 n d ∑ j = 1 m d [ g c d ( i , j ) = = 1 ] \displaystyle\sum_{i = 1}^{\frac{n}{d}}\sum_{j = 1}^{\frac{m}{d}}[gcd(i,j)==1] i = 1 ∑ d n j = 1 ∑ d m [ g c d ( i , j ) = = 1 ] 是等價的
令( 1 ) ( 2 ) (1)(2) ( 1 ) ( 2 ) 中的n = ⌊ n d ⌋ , m = ⌊ n d ⌋ , u = 1 n = \lfloor\frac{n}{d}\rfloor,m = \lfloor\frac{n}{d}\rfloor,u = 1 n = ⌊ d n ⌋ , m = ⌊ d n ⌋ , u = 1
f ( 1 ) = ∑ p μ ( p 1 ) ⌊ n d × p ⌋ ⌊ m d × p ⌋ f(1) = \displaystyle\sum_{p}\mu(\frac{p}{1})\lfloor\frac{n}{d\times p}\rfloor\lfloor\frac{m}{d\times p}\rfloor f ( 1 ) = p ∑ μ ( 1 p ) ⌊ d × p n ⌋ ⌊ d × p m ⌋ (注意此時⌊ n d × p ⌋ \lfloor\frac{n}{d\times p}\rfloor ⌊ d × p n ⌋ 中的⌊ n d ⌋ \lfloor\frac{n}{d}\rfloor ⌊ d n ⌋ 是常量,是不變換的)
a n s = ∑ d d k ∑ p μ ( p ) ⌊ n d p ⌋ ⌊ m d p ⌋ ans = \displaystyle\sum_dd^k\displaystyle\sum_{p}\mu(p)\lfloor\frac{n}{ dp}\rfloor\lfloor\frac{m}{ dp}\rfloor a n s = d ∑ d k p ∑ μ ( p ) ⌊ d p n ⌋ ⌊ d p m ⌋
爲了使形式更加明顯一些,設Q = d p Q = dp Q = d p
a n s = ∑ Q ⌊ n Q ⌋ ⌊ m Q ⌋ ∑ d ∣ Q d k μ ( Q d ) ans = \displaystyle\sum_Q\displaystyle\lfloor\frac{n}{ Q}\rfloor\lfloor\frac{m}{ Q}\rfloor \sum_{d\ |\ Q}d^k\mu(\frac{Q}{d}) a n s = Q ∑ ⌊ Q n ⌋ ⌊ Q m ⌋ d ∣ Q ∑ d k μ ( d Q )
到這裏我們設F ( Q ) = ∑ d ∣ Q d k μ ( Q d ) F(Q) = \displaystyle \sum_{d\ |\ Q}d^k\mu(\frac{Q}{d}) F ( Q ) = d ∣ Q ∑ d k μ ( d Q ) ,可以很(bu)容易發現F ( Q ) F(Q) F ( Q ) 是一個狄利克雷卷積的形式。
順便再來複習狄利克雷卷積的定義:
( f ∗ g ) ( n ) = ∑ d ∣ n f ( d ) g ( n d ) (f*g)(n) = \displaystyle\sum_{d|n}f(d)g(\frac{n}{d}) ( f ∗ g ) ( n ) = d ∣ n ∑ f ( d ) g ( d n ) 。
那麼F = i d k ∗ u F = idk*u F = i d k ∗ u
我們的答案就變成了:
a n s = ∑ Q ⌊ n Q ⌋ ⌊ m Q ⌋ F ( Q ) ans = \displaystyle\sum_Q\displaystyle\lfloor\frac{n}{ Q}\rfloor\lfloor\frac{m}{ Q}\rfloor F(Q) a n s = Q ∑ ⌊ Q n ⌋ ⌊ Q m ⌋ F ( Q )
前一部分直接使用分塊可以很好的求出,F ( Q ) F(Q) F ( Q ) 則需要使用線性篩來預處理,並求出前綴和。
根據狄利克雷卷積的性質,因爲 i d k idk i d k 和 μ \mu μ 都是積性函數所以F F F 也是積性函數,那麼F F F 就可以像φ \varphi φ 一樣利用F ( a × b ) = F ( a ) × F ( b ) F(a\times b) = F(a)\times F(b) F ( a × b ) = F ( a ) × F ( b ) 求出。
對於F ( Q ) = ∑ d ∣ Q d k μ ( Q d ) F(Q) = \displaystyle \sum_{d\ |\ Q}d^k\mu(\frac{Q}{d}) F ( Q ) = d ∣ Q ∑ d k μ ( d Q ) ,將Q按唯一分解定理分解:
Q = p 1 c 1 p 2 c 2 . . . p m c m Q = p_1^{c1}p_2^{c2}...p_m^{cm} Q = p 1 c 1 p 2 c 2 . . . p m c m
F ( Q ) = ∏ i = 1 m F ( p i c i ) . . . . . . . . ( 1 ) F(Q) = \displaystyle\prod_{i =1}^m F(p_i^{ci})........(1) F ( Q ) = i = 1 ∏ m F ( p i c i ) . . . . . . . . ( 1 )
同時,對於F ( p i c i ) F(p_i^{ci}) F ( p i c i ) ,因爲莫比烏斯函數的性質,μ ( p r i m e ) = − 1 , μ ( 1 ) = 1 \mu(prime)=-1,\mu(1)=1 μ ( p r i m e ) = − 1 , μ ( 1 ) = 1 ,所以只有在 d = p i c i − 1 d = p_i^{ci-1} d = p i c i − 1 和 d = p i c i d = p_i^{ci} d = p i c i 時對∑ d ∣ p i c i d k μ ( p i c i d ) \displaystyle \sum_{d\ |\ p_i^{ci}}d^k\mu(\frac{p_i^{ci}}{d}) d ∣ p i c i ∑ d k μ ( d p i c i ) 有貢獻。所以,( 1 ) (1) ( 1 ) 可以轉化爲:
F ( Q ) F(Q) F ( Q )
= ∏ i = 1 m ( p i k × ( c i − 1 ) × μ ( p i ) + p i k × c i × μ ( 1 ) ) \displaystyle=\prod_{i=1}^{m}(p_i^{k\times (ci-1)}\times \mu(p_i)\ +\ p_i^{k\times c_i}\times \mu(1)) = i = 1 ∏ m ( p i k × ( c i − 1 ) × μ ( p i ) + p i k × c i × μ ( 1 ) )
= ∏ i = 1 m p i k × ( c i − 1 ) × ( p i k − 1 ) \displaystyle =\prod_{i=1}^{m}p_i^{k\times (ci-1)}\times(p_i^{k}-1) = i = 1 ∏ m p i k × ( c i − 1 ) × ( p i k − 1 )
當p r i m e [ j ] ∣ i̸ prime[j] \ |\not i p r i m e [ j ] ∣ i 的時候,兩者互質,滿足積性函數的性質,f [ i ∗ p r i m e [ j ] ] = f [ i ] ∗ f [ p r i m e [ j ] ] f[i * prime[j]] = f[i] * f[prime[j]] f [ i ∗ p r i m e [ j ] ] = f [ i ] ∗ f [ p r i m e [ j ] ]
當p r i m e [ j ] ∣ i prime[j] \ |\ i p r i m e [ j ] ∣ i 的時候,f [ i ∗ p r i m e [ j ] ] = f [ i ] ∗ p r i m e [ j ] k f[i * prime[j]] = f[i] * prime[j]^k f [ i ∗ p r i m e [ j ] ] = f [ i ] ∗ p r i m e [ j ] k
第二個結論和篩φ \varphi φ 函數的時候類似,下面證明一下:
令p = p r i m e [ j ] p = prime[j] p = p r i m e [ j ]
p [ j ] ∣ i p[j] \ |\ i p [ j ] ∣ i 時,證明 i p [ j ] \frac{i}{p[j]} p [ j ] i 和 i i i 有相同的質因子,那麼
F ( i ) F ( i p ) = p i k ( c i − 1 ) × p i k − 1... p i k ( c i − 2 ) × p i k − 1... = p k \frac{F(i)}{F(\frac{i}{p})}=\frac{p_i^{k{(ci-1)}}\times p_i^k-1...}{p_i^{k{(ci-2)}}\times p_i^k-1...}=p^k F ( p i ) F ( i ) = p i k ( c i − 2 ) × p i k − 1 . . . p i k ( c i − 1 ) × p i k − 1 . . . = p k
所以,f [ i ∗ p r i m e [ j ] ] = f [ i ] ∗ p r i m e [ j ] k f[i * prime[j]] = f[i] * prime[j]^k f [ i ∗ p r i m e [ j ] ] = f [ i ] ∗ p r i m e [ j ] k 。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define ll long long
using namespace std;
const int N = 5e6 + 10 ;
const int mod = 1e9 + 7 ;
ll prime[ N] , mu[ N] , tot = 0 , f[ N] = { 0 } , g[ N] = { 0 } ;
bool prime_tag[ N] = { 0 } ;
int t, k, n, m;
ll qpow ( ll a, ll b) {
ll res = 1ll ;
while ( b) {
if ( b & 1 ) {
res = res * a % mod;
}
a = a * a % mod;
b >>= 1 ;
}
return res;
}
void init ( ) {
f[ 1 ] = 1 ;
for ( int i = 2 ; i < N; i++ ) {
if ( ! prime_tag[ i] ) {
prime[ tot] = i;
g[ tot] = qpow ( i, k) ;
f[ i] = ( g[ tot] - 1 + mod) % mod;
tot++ ;
}
for ( int j = 0 ; j < tot && i * prime[ j] < N; j++ ) {
prime_tag[ i * prime[ j] ] = true ;
if ( i % prime[ j] == 0 ) {
f[ i * prime[ j] ] = ( ll) f[ i] * g[ j] % mod;
break ;
} else
f[ i * prime[ j] ] = ( ll) f[ i] * f[ prime[ j] ] % mod;
}
}
f[ 0 ] = 0 ;
for ( int i = 1 ; i < N; i++ )
f[ i] = ( f[ i] + f[ i- 1 ] ) % mod;
}
ll solve ( ) {
ll res = 0 ;
for ( int l = 1 , r ; l <= n; l = r + 1 ) {
r = min ( n / ( n / l) , m / ( m / l) ) ;
res + = ( f[ r] - f[ l - 1 ] + mod ) % mod * ( n / l) % mod * ( m / l) % mod ;
}
return res % mod;
}
int main ( ) {
scanf ( "%d %d" , & t, & k) ;
init ( ) ;
while ( t-- ) {
scanf ( "%d %d" , & n, & m) ;
if ( n > m) swap ( n, m) ;
printf ( "%lld\n" , solve ( ) ) ;
}
return 0 ;
}
【例4】P1829 [國家集訓隊]Crash的數字表格 / JZPTAB
題意
爲了研究最小公倍數,C r a s h Crash C r a s h 畫了一張N ∗ M N*M N ∗ M 的表格,每個格子裏寫了一個數字,其中第i i i 行第j j j 列的那個格子裏寫着數L C M ( i , j ) LCM(i,j) L C M ( i , j ) 。C r a s h Crash C r a s h 想知道表格裏所有的數的和mod 20101009的值。
思路
首先將問題轉化爲數學形式,保證N < = M N<=M N < = M ,如果大就進行交換:
a n s = ∑ i = 1 N ∑ j = 1 M l c m ( i , j ) ans = \displaystyle\sum_{i =1}^{N}\sum_{j = 1}^{M}lcm(i,j) a n s = i = 1 ∑ N j = 1 ∑ M l c m ( i , j )
= ∑ i = 1 N ∑ j = 1 M i ∗ j g c d ( i , j ) = \displaystyle\sum_{i =1}^{N}\sum_{j = 1}^{M}\frac{i*j}{gcd(i,j)} = i = 1 ∑ N j = 1 ∑ M g c d ( i , j ) i ∗ j
令d = g c d ( i , j ) d = gcd(i,j) d = g c d ( i , j ) ,我們枚舉d d d ,則:
a n s = ∑ d N 1 d ∑ i N ∑ j M i × j [ g c d ( i , j ) = = d ] ans = \displaystyle\sum_{d}^{N}\frac{1}{d}\sum_{i}^{N}\sum_{j}^{M}i\times j[\ gcd(i,j)==d\ ] a n s = d ∑ N d 1 i ∑ N j ∑ M i × j [ g c d ( i , j ) = = d ]
設f ( N , M , d ) = ∑ i N ∑ j M i × j [ g c d ( i , j ) = = d ] f(N,M,d) = \displaystyle\sum_{i}^{N}\sum_{j}^{M}i\times j[\ gcd(i,j)==d\ ] f ( N , M , d ) = i ∑ N j ∑ M i × j [ g c d ( i , j ) = = d ]
設g ( N , M , d ) = ∑ i N ∑ j M i × j [ d ∣ g c d ( i , j ) ] = ∑ d ∣ i N i ∑ d ∣ j M j = d 2 × ⌊ N d ⌋ ( ⌊ N d ⌋ + 1 ) 2 × ⌊ M d ⌋ ( ⌊ M d ⌋ + 1 ) 2 g(N,M,d) = \displaystyle\sum_{i}^{N}\sum_{j}^{M}i\times j[\ d\ |\ gcd(i,j)\ ]=\sum_{d|i}^{N}i\sum_{d|j}^{M}j =d^2\times\frac{\lfloor\frac{N}{d}\rfloor(\lfloor\frac{N}{d}\rfloor+1)}{2}\times\frac{\lfloor\frac{M}{d}\rfloor(\lfloor\frac{M}{d}\rfloor+1)}{2} g ( N , M , d ) = i ∑ N j ∑ M i × j [ d ∣ g c d ( i , j ) ] = d ∣ i ∑ N i d ∣ j ∑ M j = d 2 × 2 ⌊ d N ⌋ ( ⌊ d N ⌋ + 1 ) × 2 ⌊ d M ⌋ ( ⌊ d M ⌋ + 1 )
這裏是一個循環對j j j 求和,一個循環對i i i 求和,∑ i N ∑ j M i × j \displaystyle\sum_{i}^{N}\sum_{j}^{M}i\times j i ∑ N j ∑ M i × j 和 ∑ i 1 ⌊ N d ⌋ ∑ j 1 ⌊ M d ⌋ d 2 × i 1 × j 1 \displaystyle\sum_{i_1}^{\lfloor\frac{N}{d}\rfloor}\sum_{j_1}^{\lfloor\frac{M}{d}\rfloor}d^2\times i_1\times j_1 i 1 ∑ ⌊ d N ⌋ j 1 ∑ ⌊ d M ⌋ d 2 × i 1 × j 1 等價
簡要證明:首先我們知道 i ∈ [ 1 , N ] , j ∈ [ 1 , M ] i\in[1,N],j\in[1,M] i ∈ [ 1 , N ] , j ∈ [ 1 , M ] ,滿足 g c d ( i , j ) = = d gcd(i,j) == d g c d ( i , j ) = = d 的數對個數是⌊ N d ⌋ × ⌊ M d ⌋ {\lfloor\frac{N}{d}\rfloor}\times{\lfloor\frac{M}{d}\rfloor} ⌊ d N ⌋ × ⌊ d M ⌋ ,我們將 i , j i,j i , j 除以 d d d ,縮小了範圍,將i , j i,j i , j 的範圍從 [1,N] 和 [1,M] 縮小到了 [1,⌊ N d ⌋ {\lfloor\frac{N}{d}\rfloor} ⌊ d N ⌋ ] 和[1,⌊ M d ⌋ {\lfloor\frac{M}{d}\rfloor} ⌊ d M ⌋ ],變成了i 1 , j 1 i_1,j_1 i 1 , j 1 。i = d × i 1 , j = d × j 1 i= d\times i_1,j= d\times j_1 i = d × i 1 , j = d × j 1 。
開始莫比烏斯反演:
f ( d ) = ∑ d ∣ n μ ( n d ) g ( n ) = ∑ d ∣ n μ ( n d ) × n 2 × ⌊ N n ⌋ ( ⌊ N n ⌋ + 1 ) 2 × ⌊ M n ⌋ ( ⌊ M n ⌋ + 1 ) 2 f(d) = \displaystyle\sum_{d | n}\mu(\frac{n}{d})g(n)=\sum_{d | n}\mu(\frac{n}{d})\times n^2\times\frac{\lfloor\frac{N}{n}\rfloor(\lfloor\frac{N}{n}\rfloor+1)}{2}\times\frac{\lfloor\frac{M}{n}\rfloor(\lfloor\frac{M}{n}\rfloor+1)}{2} f ( d ) = d ∣ n ∑ μ ( d n ) g ( n ) = d ∣ n ∑ μ ( d n ) × n 2 × 2 ⌊ n N ⌋ ( ⌊ n N ⌋ + 1 ) × 2 ⌊ n M ⌋ ( ⌊ n M ⌋ + 1 )
a n s = ∑ d = 1 N 1 d × f ( d ) ans = \displaystyle\sum_{d=1}^{N}\frac{1}{d}\times f(d) a n s = d = 1 ∑ N d 1 × f ( d )
a n s = ∑ d = 1 N 1 d ∑ d ∣ n μ ( n d ) × n 2 × ⌊ N n ⌋ ( ⌊ N n ⌋ + 1 ) 2 × ⌊ M n ⌋ ( ⌊ M n ⌋ + 1 ) 2 ans = \displaystyle\sum_{d =1}^{N}\frac{1}{d}\sum_{d|n}\mu(\frac{n}{d})\times n^2\times\frac{\lfloor\frac{N}{n}\rfloor(\lfloor\frac{N}{n}\rfloor+1)}{2}\times\frac{\lfloor\frac{M}{n}\rfloor(\lfloor\frac{M}{n}\rfloor+1)}{2} a n s = d = 1 ∑ N d 1 d ∣ n ∑ μ ( d n ) × n 2 × 2 ⌊ n N ⌋ ( ⌊ n N ⌋ + 1 ) × 2 ⌊ n M ⌋ ( ⌊ n M ⌋ + 1 )
令x = n d x = \frac{n}{d} x = d n ,枚舉x x x 。
a n s = ∑ d = 1 N 1 d ∑ x ⌊ N d ⌋ μ ( x ) × d 2 × x 2 × ⌊ N n ⌋ ( ⌊ N n ⌋ + 1 ) 2 × ⌊ M n ⌋ ( ⌊ M n ⌋ + 1 ) 2 ans = \displaystyle\sum_{d=1}^{N}\frac{1}{d}\sum_{x}^{\lfloor\frac{N}{d}\rfloor}\mu(x)\times d^2\times x^2\times \frac{\lfloor\frac{N}{n}\rfloor(\lfloor\frac{N}{n}\rfloor+1)}{2}\times\frac{\lfloor\frac{M}{n}\rfloor(\lfloor\frac{M}{n}\rfloor+1)}{2} a n s = d = 1 ∑ N d 1 x ∑ ⌊ d N ⌋ μ ( x ) × d 2 × x 2 × 2 ⌊ n N ⌋ ( ⌊ n N ⌋ + 1 ) × 2 ⌊ n M ⌋ ( ⌊ n M ⌋ + 1 )
a n s = ∑ d = 1 N ∑ x ⌊ N d ⌋ μ ( x ) × x × n × ⌊ N n ⌋ ( ⌊ N n ⌋ + 1 ) 2 × ⌊ M n ⌋ ( ⌊ M n ⌋ + 1 ) 2 ans = \displaystyle\sum_{d=1}^{N}\sum_{x}^{\lfloor\frac{N}{d}\rfloor}\mu(x)\times x\times n\times \frac{\lfloor\frac{N}{n}\rfloor(\lfloor\frac{N}{n}\rfloor+1)}{2}\times\frac{\lfloor\frac{M}{n}\rfloor(\lfloor\frac{M}{n}\rfloor+1)}{2} a n s = d = 1 ∑ N x ∑ ⌊ d N ⌋ μ ( x ) × x × n × 2 ⌊ n N ⌋ ( ⌊ n N ⌋ + 1 ) × 2 ⌊ n M ⌋ ( ⌊ n M ⌋ + 1 )
a n s = ∑ n = 1 N n × ⌊ N n ⌋ ( ⌊ N n ⌋ + 1 ) 2 × ⌊ M n ⌋ ( ⌊ M n ⌋ + 1 ) 2 ∑ x ∣ n μ ( x ) × x ans = \displaystyle\sum_{n=1}^{N}n\times \frac{\lfloor\frac{N}{n}\rfloor(\lfloor\frac{N}{n}\rfloor+1)}{2}\times\frac{\lfloor\frac{M}{n}\rfloor(\lfloor\frac{M}{n}\rfloor+1)}{2}\sum_{x|n}\mu(x)\times x a n s = n = 1 ∑ N n × 2 ⌊ n N ⌋ ( ⌊ n N ⌋ + 1 ) × 2 ⌊ n M ⌋ ( ⌊ n M ⌋ + 1 ) x ∣ n ∑ μ ( x ) × x
前一部分直接可以數論整除分塊,根據莫比烏斯反演的性質後一部分是一個積性函數,我們在線性篩中預處理。
設f 1 ( n ) = ∑ x ∣ n μ ( x ) × x f_1(n) =\displaystyle\sum_{x|n}\mu(x)\times x f 1 ( n ) = x ∣ n ∑ μ ( x ) × x
根據唯一分解定理:
n = p 1 c 1 p 2 c 2 p 3 c 3 . . . p k c k n = p_1^{c1} p_2^{c2} p_3^{c3}... p_k^{ck} n = p 1 c 1 p 2 c 2 p 3 c 3 . . . p k c k
f 1 ( n ) = f 1 ( p 1 c 1 p 2 c 2 p 3 c 3 . . . p k c k ) = ∏ i = 1 k p i c i \displaystyle f_1(n) = f_1(p_1^{c1} p_2^{c2} p_3^{c3}... p_k^{ck}) = \prod_{i=1}^{k}p_i^{ci} f 1 ( n ) = f 1 ( p 1 c 1 p 2 c 2 p 3 c 3 . . . p k c k ) = i = 1 ∏ k p i c i
對於f 1 ( n ) f_1(n) f 1 ( n ) ,當 n i s p r i m e n\ \ is\ \ prime n i s p r i m e 時,在求和的過程中,根據莫比烏斯函數的性質,只有當 x x x 只有 n , 1 n,1 n , 1 兩個值可取,的時候對和有貢獻。所以當 n i s p r i m e n\ \ is\ \ prime n i s p r i m e 時,f 1 ( n ) = 1 − n f_1(n)=1-n f 1 ( n ) = 1 − n 。
這樣我們線性篩的時候就很簡單了:
當 i m o d p r i m e [ j ] = = 1 i \ mod\ prime[j] == 1 i m o d p r i m e [ j ] = = 1 時,f 1 ( i ∗ p r i m e [ j ] ) = f 1 ( i ) × f 1 ( p r i m e [ j ] ) f_1(i*prime[j])=f_1(i)\times f_1(prime[j]) f 1 ( i ∗ p r i m e [ j ] ) = f 1 ( i ) × f 1 ( p r i m e [ j ] )
當 i m o d p r i m e [ j ] = = 0 i \ mod\ prime[j] == 0 i m o d p r i m e [ j ] = = 0 時,f 1 ( i ∗ p r i m e [ j ] ) = f 1 ( i ) = 1 − i f_1(i*prime[j])=f_1(i)=1-i f 1 ( i ∗ p r i m e [ j ] ) = f 1 ( i ) = 1 − i
設 p = p r i m e [ j ] p = prime[j] p = p r i m e [ j ]
.
當i m o d p = = 0 i \ mod\ p == 0 i m o d p = = 0 時,n p , n \frac{n}{p},n p n , n 都是 p p p 的倍數,
.
f 1 ( n ) f 1 ( n p ) = ( 1 − p 1 ) ( 1 − p 2 ) . . . ( 1 − p k ) ( 1 − p 1 ) ( 1 − p 2 ) . . . ( 1 − p k ) = 1 \displaystyle \frac{f_1(n)}{f_1(\frac{n}{p})}=\frac{(1-p_1)(1-p_2)...(1-p_k)}{(1-p_1)(1-p_2)...(1-p_k)}=1 f 1 ( p n ) f 1 ( n ) = ( 1 − p 1 ) ( 1 − p 2 ) . . . ( 1 − p k ) ( 1 − p 1 ) ( 1 − p 2 ) . . . ( 1 − p k ) = 1
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define ll long long
using namespace std;
const int mod = 20101009 ;
const int Max = 1e7 + 10 ;
int prime[ Max] , prime_tot = 0 , f[ Max] , s[ Max] ;
bool prime_tag[ Max] = { 0 } ;
int n, m;
void get_prime ( ) {
f[ 1 ] = 1 ;
for ( int i = 2 ; i < Max; i++ ) {
if ( ! prime_tag[ i] ) {
prime[ prime_tot++ ] = i;
f[ i] = ( 1 - i + mod) % mod;
}
for ( int j = 0 ; j < prime_tot && i * prime[ j] < Max; j++ ) {
prime_tag[ i * prime[ j] ] = true ;
if ( i % prime[ j] == 0 ) {
f[ i * prime[ j] ] = f[ i] ;
break ;
} else {
f[ i * prime[ j] ] = 1ll * f[ i] * f[ prime[ j] ] % mod ;
}
}
}
f[ 0 ] = 0 ;
for ( int i = 1 ; i < Max; i++ )
f[ i] = ( f[ i- 1 ] + 1ll * f[ i] * i % mod) % mod;
}
ll solve ( ) {
ll ans = 0 , t1, t2, t3;
for ( int l = 1 , r; l <= n; l = r + 1 ) {
r = min ( n / ( n / l) , m / ( m / l) ) ;
t1 = 1ll * ( f[ r] - f[ l- 1 ] + mod ) % mod;
t2 = 1ll * ( n / l) * ( n / l + 1 ) / 2 % mod;
t3 = 1ll * ( m / l) * ( m / l + 1 ) / 2 % mod;
ans + = t1 % mod * t2 % mod * t3 % mod ;
}
return ans % mod;
}
int main ( ) {
get_prime ( ) ;
scanf ( "%d%d" , & n, & m) ;
if ( n > m) swap ( n, m) ;
printf ( "%lld" , solve ( ) ) ;
return 0 ;
}