Define function
fn(k)=∑l1=1n∑l2=1n…∑lk=1n(gcd(l1,l2,…,lk))2\displaystyle f_n(k)=\sum_{l_1=1}^n \sum_{l_2=1}^n … \sum_{l_k=1}^n (\gcd(l_1,l_2,…,l_k))^2 fn(k)=l1=1∑nl2=1∑n…lk=1∑n(gcd(l1,l2,…,lk))2
.
Given n(1≤n≤109),k(2≤k≤10105)n(1 \le n \le 10^9),k(2 \le k \le {10}{10 5})n(1≤n≤109),k(2≤k≤10105), please calculate
∑i=2kfn(i)\displaystyle∑ i = 2 k f n ( i ) i = 2 ∑ k f n ( i ) \sum_{i=2}^k {f_n(i)} i=2∑kfn(i) ∑ i = 2 k f n ( i ) i = 2 ∑ k f n ( i )
modulo 109+710^9 + 7109+7.
Input
There are multiple test cases, the first line contains an integer T(1≤T≤10)T(1 \le T \le 10)T(1≤T≤10), denoting the number of test cases.
For the next TTT lines, each line contains two integers n(1≤n≤109)n(1 \le n \le 10^9)n(1≤n≤109) and k(2≤k≤10105)k(2 \le k \le 10{10 5})k(2≤k≤10105).
Output
For each test case, print one line contains an integer, which is the value of ∑i=2kfn(i)\sum_{i=2}^k {f_n(i)}∑i=2kfn(i).
樣例輸入
2
2 2
100 3
樣例輸出
7
4331084
分析:
已 知 : f ( k ) = ∑ l 1 = 1 n ∑ l 2 = 1 n ⋯ ∑ l k = 1 n ( g c d ( l 1 , l 2 , ⋯ , l k ) ) 2 求 ∑ i = 2 k f ( i ) 已知:f(k)=\sum_{l_1=1}^n{\sum_{l_2=1}^n{\cdots \sum_{l_k=1}^n{(gcd(l_1,l_2,\cdots,l_k))^2}}}
\\ 求\sum_{i=2}^k{f(i)} 已 知 : f ( k ) = l 1 = 1 ∑ n l 2 = 1 ∑ n ⋯ l k = 1 ∑ n ( g c d ( l 1 , l 2 , ⋯ , l k ) ) 2 求 i = 2 ∑ k f ( i )
推式子:
f ( k ) = ∑ l 1 = 1 n ∑ l 2 = 1 n ⋯ ∑ l k = 1 n ( g c d ( l 1 , l 2 , ⋯ , l k ) ) 2 = ∑ l 1 = 1 n ∑ l 2 = 1 n ⋯ ∑ l k = 1 n ∑ d = 1 n d 2 [ g c d ( l 1 , l 2 , ⋯ , l k ) = d ] = ∑ d = 1 n d 2 ∑ l 1 = 1 n d ∑ l 2 = 1 n d ⋯ ∑ l k = 1 n d [ g c d ( l 1 , l 2 , ⋯ , l k ) = = 1 ] = ∑ d = 1 n d 2 ∑ l 1 = 1 n d ∑ l 2 = 1 n d ⋯ ∑ l k = 1 n d ( ∑ i ∣ g c d ( l 1 , l 2 , ⋯ , l k ) μ ( i ) ∗ 1 ) 莫 比 烏 斯 反 演 = ∑ d = 1 n d 2 ∑ i = 1 n d μ ( i ) ∑ l 1 = 1 n d ∑ l 2 = 1 n d ⋯ ∑ l k = 1 n d [ i ∣ l 1 ] [ i ∣ l 2 ] ⋯ [ i ∣ l k ] = ∑ d = 1 n d 2 ∑ i = 1 n d μ ( i ) ( n i ∗ d ) k 爲 了 將 k 次 方 化 成 便 於 計 算 的 , 令 t = i ∗ d , 則 有 i ∣ t , d = t / i = ∑ t = 1 n ( n t ) k ∑ i ∣ t μ ( i ) ( t i ) 2 f(k)=\sum_{l_1=1}^n{\sum_{l_2=1}^n{\cdots \sum_{l_k=1}^n{(gcd(l_1,l_2,\cdots,l_k))^2}}}
\\ = \sum_{l_1=1}^n{\sum_{l_2=1}^n{\cdots \sum_{l_k=1}^n{\sum_{d=1}^n{d^2}}[gcd(l_1,l_2,\cdots,l_k)=d]}}
\\ =\sum_{d=1}^nd^2\sum_{l_1=1}^{\frac{n}{d}}\sum_{l_2=1}^{\frac{n}{d}}\cdots\sum_{l_k=1}^{\frac{n}{d}}{[gcd(l_1,l_2,\cdots , l_k)==1]}
\\ = \sum_{d=1}^nd^2\sum_{l_1=1}^{\frac{n}{d}}\sum_{l_2=1}^{\frac{n}{d}}\cdots\sum_{l_k=1}^{\frac{n}{d}}{\;\;\;(\sum_{i|gcd(l_1,l_2,\cdots,l_k)}{\mu(i)*1})} \;\;\;\;\;\;\;\;\;\;\;\;{莫比烏斯反演}
\\ = \sum_{d=1}^n{d^2}\sum_{i=1}^{\frac{n}{d}}{\mu(i)\sum_{l_1=1}^{\frac{n}{d}}\sum_{l_2=1}^{\frac{n}{d}}\cdots\sum_{l_k=1}^{\frac{n}{d}}[i|l_1][i|l_2]\cdots[i|l_k]}
\\=\sum_{d=1}^nd^2\sum_{i=1}^{\frac{n}{d}}\mu(i)(\frac{n}{i*d})^k
\\爲了將k次方化成便於計算的,令t=i*d,則有i|t,d=t/i
\\=\sum_{t=1}^n(\frac{n}{t})^k \sum_{i|t}\mu(i)(\frac{t}{i})^2 f ( k ) = l 1 = 1 ∑ n l 2 = 1 ∑ n ⋯ l k = 1 ∑ n ( g c d ( l 1 , l 2 , ⋯ , l k ) ) 2 = l 1 = 1 ∑ n l 2 = 1 ∑ n ⋯ l k = 1 ∑ n d = 1 ∑ n d 2 [ g c d ( l 1 , l 2 , ⋯ , l k ) = d ] = d = 1 ∑ n d 2 l 1 = 1 ∑ d n l 2 = 1 ∑ d n ⋯ l k = 1 ∑ d n [ g c d ( l 1 , l 2 , ⋯ , l k ) = = 1 ] = d = 1 ∑ n d 2 l 1 = 1 ∑ d n l 2 = 1 ∑ d n ⋯ l k = 1 ∑ d n ( i ∣ g c d ( l 1 , l 2 , ⋯ , l k ) ∑ μ ( i ) ∗ 1 ) 莫 比 烏 斯 反 演 = d = 1 ∑ n d 2 i = 1 ∑ d n μ ( i ) l 1 = 1 ∑ d n l 2 = 1 ∑ d n ⋯ l k = 1 ∑ d n [ i ∣ l 1 ] [ i ∣ l 2 ] ⋯ [ i ∣ l k ] = d = 1 ∑ n d 2 i = 1 ∑ d n μ ( i ) ( i ∗ d n ) k 爲 了 將 k 次 方 化 成 便 於 計 算 的 , 令 t = i ∗ d , 則 有 i ∣ t , d = t / i = t = 1 ∑ n ( t n ) k i ∣ t ∑ μ ( i ) ( i t ) 2
∑ i = 2 k f ( i ) \sum_{i=2}^kf(i) ∑ i = 2 k f ( i ) 將f(i)代入得:(f(i)中變量名換下)
= ∑ i = 2 k ∑ t = 1 n ( n t ) i ∑ d ∣ t μ ( d ) ( t d ) 2 = ∑ t = 1 n ( ∑ i = 2 k ( n t ) i ) ∑ d ∣ t μ ( d ) ( t d ) 2 (1) =\sum_{i=2}^k{\sum_{t=1}^n(\frac{n}{t})^i \sum_{d|t}\mu(d)(\frac{t}{d})^2}
\\ =\sum_{t=1}^n(\sum_{i=2}^k(\frac{n}{t})^i) \sum_{d|t}\mu(d)(\frac{t}{d})^2\tag{1} = i = 2 ∑ k t = 1 ∑ n ( t n ) i d ∣ t ∑ μ ( d ) ( d t ) 2 = t = 1 ∑ n ( i = 2 ∑ k ( t n ) i ) d ∣ t ∑ μ ( d ) ( d t ) 2 ( 1 )
對於∑ i = 2 k ( n t ) i \sum_{i=2}^k(\frac{n}{t})^i ∑ i = 2 k ( t n ) i 這部分可以利用等比數列求解,並對公比爲1的情況特判,只需將k%mod,其餘情況k%φ(mod),
對於後面那部分:令 s ( t ) = ∑ d ∣ t μ ( d ) ( t d ) 2 令s(t)=\sum_{d|t}\mu(d)(\frac{t}{d})^2 令 s ( t ) = ∑ d ∣ t μ ( d ) ( d t ) 2 ,這個函數s(t)是積性函數,s ( 1 ) = 1 , s ( p ) = p ∗ p − 1 , s ( p k ) = p 2 k − 2 ( p 2 − 1 ) s(1)=1,s(p)=p*p-1,s(p^k)=p^{2k-2}(p^2-1) s ( 1 ) = 1 , s ( p ) = p ∗ p − 1 , s ( p k ) = p 2 k − 2 ( p 2 − 1 ) ,對於s函數在線性篩中,稍微推下,就可推出
在(1)式中,n/t可以利用分塊, 故要對s函數求前綴和,令前i個和爲sum(i),前綴和杜教篩推導:
前 置 知 識 : i d ( i ) = i , I ( i ) = 1 ; 卷 積 ; 令 g ( i ) = i 2 則 有 s = μ ∗ g 又 μ ∗ I = [ i = = 1 ] 令 h = s ∗ I = μ ∗ I ∗ g = g , 即 h ( i ) = i 2 推 s u m ( i ) ∑ i = 1 n h ( i ) = ∑ i = 1 n ∑ d ∣ i I ( d ) ∗ s ( i / d ) ∑ i = 1 n h ( i ) = ∑ d = 1 n I ( d ) ∑ k = 1 n d s ( k ) = ∑ d = 1 n I ( d ) s u m ( n d ) 提 出 右 邊 的 d = 1 ∑ i = 1 n h ( i ) = I ( 1 ) s u m ( n ) + ∑ d = 2 n I ( d ) s u m ( n d ) h , I 函 數 代 入 得 s u m ( n ) = ∑ i = 1 n i 2 − ∑ d = 2 n s u m ( n d ) 前置知識:id(i)=i,I(i)=1;卷積;\\令g(i)=i^2\\則有s=\mu*g
\\ 又\mu*I=[i==1]\\
令h=s*I=\mu*I*g=g,即h(i)=i^2\\
\\ 推sum(i)\\
\sum_{i=1}^nh(i)=\sum_{i=1}^n\sum_{d|i}I(d)*s(i/d)
\\ \sum_{i=1}^nh(i)=\sum_{d=1}^nI(d)\sum_{k=1}^{\frac{n}{d}}s(k)=\sum_{d=1}^nI(d)sum(\frac{n}{d})
\\提出右邊的d=1
\\ \sum_{i=1}^nh(i)=I(1)sum(n)+\sum_{d=2}^nI(d)sum(\frac{n}{d})
\\ h,I函數代入得
sum(n)=\sum_{i=1}^ni^2-\sum_{d=2}^nsum(\frac{n}{d}) 前 置 知 識 : i d ( i ) = i , I ( i ) = 1 ; 卷 積 ; 令 g ( i ) = i 2 則 有 s = μ ∗ g 又 μ ∗ I = [ i = = 1 ] 令 h = s ∗ I = μ ∗ I ∗ g = g , 即 h ( i ) = i 2 推 s u m ( i ) i = 1 ∑ n h ( i ) = i = 1 ∑ n d ∣ i ∑ I ( d ) ∗ s ( i / d ) i = 1 ∑ n h ( i ) = d = 1 ∑ n I ( d ) k = 1 ∑ d n s ( k ) = d = 1 ∑ n I ( d ) s u m ( d n ) 提 出 右 邊 的 d = 1 i = 1 ∑ n h ( i ) = I ( 1 ) s u m ( n ) + d = 2 ∑ n I ( d ) s u m ( d n ) h , I 函 數 代 入 得 s u m ( n ) = i = 1 ∑ n i 2 − d = 2 ∑ n s u m ( d n )
然後利用杜教篩的這個式子分塊求sum(i)
代碼:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const ll mod = 1e9 + 7 ;
const ll N= 3e6 + 5 ;
int prime[ N+ 1 ] ;
ll s[ N+ 1 ] ;
ll sum[ N+ 1 ] ;
unordered_map< int , ll> mpsum;
char str[ N] ;
void init_prime ( )
{
s[ 1 ] = 1 ;
sum[ 1 ] = 1 ;
for ( int i= 2 ; i<= N; i++ )
{
if ( ! prime[ i] )
{
prime[ ++ prime[ 0 ] ] = i;
s[ i] = ( ( 1LL * i* i- 1 ) % mod+ mod) % mod;
}
for ( int j= 1 ; j<= prime[ 0 ] && i* prime[ j] <= N; j++ )
{
prime[ i* prime[ j] ] = 1 ;
if ( i% prime[ j] == 0 )
{
s[ i* prime[ j] ] = 1LL * prime[ j] * prime[ j] % mod* s[ i] % mod;
break ;
}
s[ i* prime[ j] ] = 1LL * s[ prime[ j] ] * s[ i] % mod;
}
sum[ i] = ( sum[ i- 1 ] + s[ i] ) % mod;
}
}
ll get_sum ( ll n)
{
if ( n<= N) return sum[ n] ;
if ( mpsum. count ( n) ) return mpsum[ n] ;
ll ans= 1LL * n* ( n+ 1 ) % mod* ( ( 1ll * 2 * n+ 1 ) % mod) % mod* ( ( mod+ 1 ) / 6 ) % mod;
for ( int l= 2 , r; l<= n; l= r+ 1 )
{
r= n/ ( n/ l) ;
ans - = 1LL * ( r- l+ 1 ) * get_sum ( n/ l) ;
}
ans= ( ans% mod+ mod) % mod;
return mpsum[ n] = ans;
}
ll mul ( ll a, ll b)
{
ll ans= 1 ;
ll bs= a;
while ( b)
{
if ( b& 1 )
ans= ans* bs% mod;
b>>= 1 ;
bs= bs* bs% mod;
}
return ans;
}
ll get_k ( char * str, ll& k2)
{
int len= strlen ( str) ;
ll p= 0 ;
k2= 0 ;
for ( int i= 0 ; i< len; i++ )
{
p= 1ll * 10 * p+ str[ i] - '0' ;
k2= 1ll * 10 * k2+ str[ i] - '0' ;
if ( p>= mod- 1 )
p% = ( mod- 1 ) ;
if ( k2>= mod)
k2% = mod;
}
return p;
}
ll fp ( ll a, ll k, ll k2)
{
if ( a== 1 ) return ( ( k2- 1 ) % mod+ mod) % mod;
return mul ( a- 1 , mod- 2 ) * ( ( ( mul ( a, k+ 1 ) - 1LL * a* a) % mod+ mod) % mod) % mod;
}
ll solve ( ll n, ll k, ll k2)
{
ll ans= 0 ;
ll w, tmp;
ll x, y;
for ( int l= 1 , r; l<= n; l= r+ 1 )
{
r= n/ ( n/ l) ;
ans + = ( get_sum ( r) - get_sum ( l- 1 ) ) % mod* fp ( n/ l, k, k2) % mod;
}
ans% = mod;
if ( ans< 0 ) ans+ = mod;
return ans;
}
int main ( )
{
init_prime ( ) ;
ll t, n ;
ll k;
ll k2;
scanf ( "%lld" , & t) ;
while ( t-- )
{
scanf ( "%lld %s" , & n, str) ;
k= get_k ( str, k2) ;
printf ( "%lld\n" , solve ( n, k, k2) ) ;
}
return 0 ;
}