标题
有函数
f
n
(
k
)
=
∑
l
1
=
1
n
∑
l
2
=
1
n
⋯
∑
l
k
=
1
n
g
c
d
(
l
1
,
l
2
,
⋯
 
,
l
k
)
2
f_{n}(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
fn(k)=l1=1∑nl2=1∑n⋯lk=1∑ngcd(l1,l2,⋯,lk)2
求
∑
i
=
2
k
f
n
(
i
)
m
o
d
  
1
e
9
+
7
\sum_{i=2}^kf_n(i)\mod 1e9+7
i=2∑kfn(i)mod1e9+7
其中
1
≤
n
≤
1
0
9
1\le n\le 10^9
1≤n≤109,
2
≤
k
≤
1
0
1
0
5
2\le k \le 10^{10^5}
2≤k≤10105
思路
第一步我们肯定先对
f
n
(
k
)
f_n(k)
fn(k)进行化简,先把
g
c
d
gcd
gcd提出来
f
n
(
k
)
=
∑
d
=
1
n
d
2
∑
l
1
=
1
n
∑
l
2
=
1
n
⋯
∑
l
k
=
1
n
[
g
c
d
(
l
1
,
l
2
,
⋯
 
,
l
k
)
=
=
d
]
f_n(k)=\sum_{d=1}^nd^2\sum_{l_1=1}^{n}\sum_{l_2=1}^{n}\cdots\sum_{l_k=1}^{n}[gcd(l_1,l_2,\cdots,l_k)==d]
fn(k)=d=1∑nd2l1=1∑nl2=1∑n⋯lk=1∑n[gcd(l1,l2,⋯,lk)==d]
后面部分都除个
d
d
d
f
n
(
k
)
=
∑
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
]
f_n(k)=\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]
fn(k)=d=1∑nd2l1=1∑dnl2=1∑dn⋯lk=1∑dn[gcd(l1,l2,⋯,lk)==1]
将
∑
d
∣
g
c
d
(
l
1
,
l
2
,
⋯
 
,
l
k
)
μ
(
d
)
=
[
g
c
d
(
l
1
,
l
2
,
⋯
 
,
l
k
)
=
=
1
]
\sum_{d|gcd(l_1,l_2,\cdots,l_k)}\mu(d)=[gcd(l_1,l_2,\cdots,l_k)==1]
∑d∣gcd(l1,l2,⋯,lk)μ(d)=[gcd(l1,l2,⋯,lk)==1]带入
f
n
(
k
)
=
∑
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
)
f_n(k)=\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)
fn(k)=d=1∑nd2l1=1∑dnl2=1∑dn⋯lk=1∑dni∣gcd(l1,l2,⋯,lk)∑μ(i)
将
i
i
i提出有,及枚举1到
n
d
\frac{n}{d}
dn内的倍数,所以有
f
n
(
k
)
=
∑
d
=
1
n
d
2
∑
i
=
1
n
d
μ
(
i
)
∑
l
1
=
1
n
i
d
∑
l
2
=
1
n
i
d
⋯
∑
l
k
=
1
n
i
d
1
f_n(k)=\sum_{d=1}^nd^2\sum_{i=1}^{\frac{n}{d}}\mu(i)\sum_{l_1=1}^{\frac{n}{id}}\sum_{l_2=1}^{\frac{n}{id}}\cdots\sum_{l_k=1}^{\frac{n}{id}}1
fn(k)=d=1∑nd2i=1∑dnμ(i)l1=1∑idnl2=1∑idn⋯lk=1∑idn1
后面的部分及
n
i
d
\frac{n}{id}
idn的
k
k
k次幂即
f
n
(
k
)
=
∑
d
=
1
n
d
2
∑
i
=
1
n
d
μ
(
i
)
⌊
n
i
d
⌋
k
f_n(k)=\sum_{d=1}^nd^2\sum_{i=1}^{\frac{n}{d}}\mu(i)\left \lfloor \frac{n}{id} \right \rfloor^k
fn(k)=d=1∑nd2i=1∑dnμ(i)⌊idn⌋k上式等价于
f
n
(
k
)
=
∑
d
=
1
n
d
2
∑
i
d
=
1
n
μ
(
i
)
⌊
n
i
d
⌋
k
f_n(k)=\sum_{d=1}^nd^2\sum_{id=1}^{n}\mu(i)\left \lfloor \frac{n}{id} \right \rfloor^k
fn(k)=d=1∑nd2id=1∑nμ(i)⌊idn⌋k
我们令
T
=
i
d
T=id
T=id带入有
f
n
(
k
)
=
∑
d
=
1
n
∑
T
=
1
n
[
T
%
d
=
=
0
]
d
2
μ
(
T
d
)
⌊
n
T
⌋
k
f_n(k)=\sum_{d=1}^n\sum_{T=1}^{n}[T\%d==0]d^2\mu(\frac{T}{d})\left \lfloor \frac{n}{T} \right \rfloor^k
fn(k)=d=1∑nT=1∑n[T%d==0]d2μ(dT)⌊Tn⌋k
这里可以看作枚举的是
1
1
1到
n
n
n中每一个
d
d
d的倍数,那么我们也等价于枚举
1
1
1到
n
n
n中每个数
T
T
T的因子
f
n
(
k
)
=
∑
T
=
1
n
⌊
n
T
⌋
k
∑
d
∣
T
d
2
μ
(
T
d
)
f_n(k)=\sum_{T=1}^n\left \lfloor \frac{n}{T} \right \rfloor^k\sum_{d|T}d^2\mu(\frac{T}{d})
fn(k)=T=1∑n⌊Tn⌋kd∣T∑d2μ(dT)
然后我们考虑求解设有函数
S
(
n
)
S(n)
S(n),
f
(
n
)
f(n)
f(n)
S
(
n
)
=
∑
i
=
1
n
f
(
i
)
=
∑
i
=
1
n
∑
d
∣
T
d
2
μ
(
T
d
)
S(n)=\sum_{i=1}^nf(i)=\sum_{i=1}^n\sum_{d|T}d^2\mu(\frac{T}{d})
S(n)=i=1∑nf(i)=i=1∑nd∣T∑d2μ(dT)
对于函数
f
(
n
)
f(n)
f(n)为
I
d
2
Id^2
Id2和
μ
\mu
μ的迪利克雷卷积即
f
(
n
)
=
(
I
d
2
∗
μ
)
(
n
)
f(n)=(Id^2*\mu)(n)
f(n)=(Id2∗μ)(n)
我们又知道
μ
∗
I
=
e
\mu*I=e
μ∗I=e
我们令
g
(
n
)
=
I
(
n
)
=
1
g(n)=I(n)=1
g(n)=I(n)=1让
g
g
g和
f
f
f进行卷积然后对其求和,即用杜教筛
∑
i
=
1
n
g
∗
f
=
∑
i
=
1
n
I
d
2
(
i
)
=
∑
i
=
1
n
i
2
=
n
(
n
+
1
)
(
2
n
+
1
)
6
\sum_{i=1}^ng*f=\sum_{i=1}^nId^2(i)=\sum_{i=1}^ni^2=\frac{n(n+1)(2n+1)}{6}
i=1∑ng∗f=i=1∑nId2(i)=i=1∑ni2=6n(n+1)(2n+1)
所以这两个函数的卷积的前缀和是很好求的
∑
i
=
1
n
∑
d
∣
i
g
(
d
)
f
(
i
d
)
\sum_{i=1}^n\sum_{d|i}g(d)f(\frac{i}{d})
i=1∑nd∣i∑g(d)f(di)
对于这个式子是枚举1到n中每个数的因子的,他和枚举1到n中每个数的倍数是等价的那就有
∑
i
=
1
n
∑
d
∣
i
g
(
d
)
f
(
i
d
)
=
∑
d
=
1
n
∑
i
=
1
⌊
n
d
⌋
g
(
d
)
f
(
i
)
=
∑
d
=
1
n
g
(
d
)
∑
i
=
1
⌊
n
d
⌋
f
(
i
)
=
∑
d
=
1
n
g
(
d
)
S
(
⌊
n
d
⌋
)
\sum_{i=1}^n\sum_{d|i}g(d)f(\frac{i}{d})=\sum_{d=1}^n\sum_{i=1}^{\left \lfloor \frac{n}{d} \right \rfloor}g(d)f(i)=\sum_{d=1}^ng(d)\sum_{i=1}^{\left \lfloor \frac{n}{d} \right \rfloor}f(i)=\sum_{d=1}^ng(d)S(\left \lfloor \frac{n}{d} \right \rfloor)
i=1∑nd∣i∑g(d)f(di)=d=1∑ni=1∑⌊dn⌋g(d)f(i)=d=1∑ng(d)i=1∑⌊dn⌋f(i)=d=1∑ng(d)S(⌊dn⌋)
∑
d
=
1
n
g
(
d
)
S
(
⌊
n
d
⌋
)
=
g
(
1
)
S
(
n
)
+
∑
d
=
2
n
g
(
d
)
S
(
⌊
n
d
⌋
)
=
∑
i
=
1
n
i
2
\sum_{d=1}^ng(d)S(\left \lfloor \frac{n}{d} \right \rfloor)=g(1)S(n)+\sum_{d=2}^ng(d)S(\left \lfloor \frac{n}{d} \right \rfloor)=\sum_{i=1}^ni^2
d=1∑ng(d)S(⌊dn⌋)=g(1)S(n)+d=2∑ng(d)S(⌊dn⌋)=i=1∑ni2
g
(
1
)
S
(
n
)
=
∑
i
=
1
n
i
2
−
∑
d
=
2
n
g
(
d
)
S
(
⌊
n
d
⌋
)
g(1)S(n)=\sum_{i=1}^ni^2-\sum_{d=2}^ng(d)S(\left \lfloor \frac{n}{d} \right \rfloor)
g(1)S(n)=i=1∑ni2−d=2∑ng(d)S(⌊dn⌋)
由于
g
(
n
)
=
1
g(n)=1
g(n)=1,所以
S
(
n
)
=
n
(
n
+
1
)
(
2
n
+
1
)
6
−
∑
d
=
2
n
S
(
⌊
n
d
⌋
)
S(n)=\frac{n(n+1)(2n+1)}{6}-\sum_{d=2}^nS(\left \lfloor \frac{n}{d} \right \rfloor)
S(n)=6n(n+1)(2n+1)−d=2∑nS(⌊dn⌋)
对于
f
f
f函数我们要先预处理一部分前缀和这样可以降低杜教筛的复杂度
f f f函数是一个积性函数,显然可以用积性函数线性筛,即记录一个 l o w [ i ] low[i] low[i], l o w [ i ] low[i] low[i]的含义是记录将i唯一分解后最小的质数的次幂,即 l o w [ i ] = p k low[i]=p^k low[i]=pk,那么在线性筛中当 i % p r i m e [ j ] = = 0 i\%prime[j]==0 i%prime[j]==0时, i l o w [ i ] \frac{i}{low[i]} low[i]i和 l o w [ i ] ∗ p r i m e [ j ] low[i]*prime[j] low[i]∗prime[j]肯定是互质的,那么就可以通过积性函数的性质互质的两个数 f ( i ) ∗ f ( j ) = f ( i j ) f(i)*f(j)=f(ij) f(i)∗f(j)=f(ij),所以 f [ i ∗ p r i m e [ j ] ] = f [ i / l o w [ i ] ] ∗ f [ l o w [ i ] ∗ p r i m e [ j ] ] f[i*prime[j]]=f[i/low[i]]*f[low[i]*prime[j]] f[i∗prime[j]]=f[i/low[i]]∗f[low[i]∗prime[j]]。但是还有一种情况就是当 i = = l o w [ i ] i==low[i] i==low[i]时, i i i中不含有其他因子那么有我们要处理一下 f ( p k ) f(p^k) f(pk)这种,通过手写几项就可以发现有递推式 f [ i ∗ p r i m e [ j ] ] = f [ i ] ∗ p r i m e [ j ] f[i*prime[j]]=f[i]*prime[j] f[i∗prime[j]]=f[i]∗prime[j],即 f ( p k + 1 ) = f ( p k ) ∗ p f(p^{k+1})=f(p^k)*p f(pk+1)=f(pk)∗p,这样就可以筛了
再回到原函数
f
n
(
k
)
f_n(k)
fn(k)中,有
l
a
s
t
=
n
n
T
last=\frac{n}{\frac{n}{T}}
last=Tnn,那么
f
n
(
k
)
f_n(k)
fn(k)就可以分块做有
f
n
(
k
)
=
∑
T
=
1
n
(
S
(
l
a
s
t
)
−
S
(
T
−
1
)
)
⌊
n
T
⌋
k
f_n(k)=\sum_{T=1}^n(S(last)-S(T-1))\left \lfloor \frac{n}{T} \right \rfloor^k
fn(k)=T=1∑n(S(last)−S(T−1))⌊Tn⌋k
题目要求的是
∑
i
=
2
k
f
n
(
i
)
=
∑
T
=
1
n
(
S
(
l
a
s
t
)
−
S
(
T
−
1
)
)
∑
i
=
2
k
⌊
n
T
⌋
i
\sum_{i=2}^kf_n(i)=\sum_{T=1}^n(S(last)-S(T-1))\sum_{i=2}^k\left \lfloor \frac{n}{T} \right \rfloor^i
i=2∑kfn(i)=T=1∑n(S(last)−S(T−1))i=2∑k⌊Tn⌋i
令
q
=
⌊
n
T
⌋
q=\left \lfloor \frac{n}{T} \right \rfloor
q=⌊Tn⌋,那么后面就是一个等比数列求和有
∑
i
=
2
k
f
n
(
i
)
=
∑
T
=
1
n
(
S
(
l
a
s
t
)
−
S
(
T
−
1
)
)
q
k
+
1
−
q
2
q
−
1
\sum_{i=2}^kf_n(i)=\sum_{T=1}^n(S(last)-S(T-1))\frac{q^{k+1}-q^2}{q-1}
i=2∑kfn(i)=T=1∑n(S(last)−S(T−1))q−1qk+1−q2
注意还有公比为
1
1
1的情况,所以实际上的答案为
∑
i
=
2
k
f
n
(
i
)
=
∑
T
=
1
n
(
S
(
l
a
s
t
)
−
S
(
T
−
1
)
)
q
k
+
1
−
q
2
q
−
1
[
q
!
=
1
]
+
(
S
(
l
a
s
t
)
−
S
(
T
−
1
)
)
(
k
−
1
)
[
q
=
=
1
]
\sum_{i=2}^kf_n(i)=\sum_{T=1}^n(S(last)-S(T-1))\frac{q^{k+1}-q^2}{q-1}[q!=1]+(S(last)-S(T-1))(k-1)[q==1]
i=2∑kfn(i)=T=1∑n(S(last)−S(T−1))q−1qk+1−q2[q!=1]+(S(last)−S(T−1))(k−1)[q==1]
还有一点值得注意的是他的
k
k
k很大,在求解
q
k
+
1
q^{k+1}
qk+1次幂的时候要用上欧拉降幂这个时候对输入的
k
m
o
d
  
1
e
9
+
6
k\mod 1e9+6
kmod1e9+6,而当公比为
1
1
1的时候用的是输入的
k
m
o
d
  
1
e
9
+
7
k\mod 1e9+7
kmod1e9+7,记录两个
k
k
k的值
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
const int mod=1e9+7;
const int p=mod-1;
const int inv6=166666668;
bool vis[N];
int prime[N];
long long f[N];
int low[N];
int cnt;
void init()
{
f[1]=low[1]=1;
cnt=0;
for(int i=2; i<N; i++)
{
if(!vis[i])
{
prime[cnt++]=i;
f[i]=(1ll*i*i-1+mod)%mod;
low[i]=i;
}
for(int j=0; j<cnt&&i*prime[j]<N; j++)
{
vis[i*prime[j]]=1;
if(i%prime[j]==0)
{
low[i*prime[j]]=low[i]*prime[j];
if(i==low[i])
{
f[i*prime[j]]=f[i]*prime[j]%mod*prime[j]%mod;
}
else
{
f[i*prime[j]]=f[i/low[i]]*f[low[i]*prime[j]]%mod;
}
break;
}
else
{
low[i*prime[j]]=prime[j];
f[i*prime[j]]=f[i]*f[prime[j]]%mod;
}
}
}
for(int i=1; i<N; i++)
f[i]=(f[i-1]+f[i])%mod;
}
map<long long,long long>F;
long long S(long long n)
{
if(n<N) return f[n];
if(F.find(n)!=F.end()) return F[n];
long long sum=n*(n+1)%mod*(2*n+1)%mod*inv6%mod;
for(long long i=2,last; i<=n; i=last+1)
{
last=n/(n/i);
sum=(sum-(last-i+1)%mod*S(n/i)%mod+mod)%mod;
}
F[n]=sum;
return sum;
}
long long quickmod(long long a,long long b)
{
long long ans=1;
while(b)
{
if(b%2==1)
ans=ans*a%mod;
a=a*a%mod;
b=b/2;
}
return ans;
}
char str[100005];
int main()
{
init();
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d%s",&n,str);
long long k1=0;
long long k2=0;
int len=strlen(str);
for(int i=0;i<len;i++)
{
k1=k1*10+str[i]-'0';
k1%=p;
k2=k2*10+str[i]-'0';
k2%=mod;
}
long long ans=0;
for(int i=1,last;i<=n; i=last+1)
{
last=n/(n/i);
if((n/i)!=1)
{
ans=(ans+(S(last)-S(i-1)+mod)%mod*(quickmod(n/i,k1+1)%mod-1ll*(n/i)*(n/i)%mod+mod)%mod*quickmod(n/i-1,mod-2)%mod)%mod;
}
else
{
ans=(ans+(S(last)-S(i-1)+mod)%mod*((k2-1+mod)%mod)%mod)%mod;
}
}
printf("%lld\n",ans);
}
return 0;
}