The Preliminary Contest for ICPC Asia Nanjing 2019
E题 K Sum
题意:定义
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\limits_{l_1=1}^{n}\sum\limits_{l_2=1}^{n}…\sum\limits_{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
计算:
∑
i
=
2
k
f
n
(
i
)
m
o
d
u
l
o
1
0
9
+
7
,
1
≤
n
≤
1
0
9
,
2
≤
k
≤
1
0
1
0
5
\sum\limits_{i=2}^{k}f_n(i)\ modulo\ 10^9+7,1\leq n\leq 10^9,2\leq k\leq10^{10^5}
i=2∑kfn(i) modulo 109+7,1≤n≤109,2≤k≤10105
题解:
f
n
(
i
)
=
∑
l
1
=
1
n
∑
l
2
=
1
n
…
∑
l
i
=
1
n
(
g
c
d
(
l
1
,
l
2
,
…
,
l
i
)
)
2
f_n(i)=\sum\limits_{l_1=1}^{n}\sum\limits_{l_2=1}^{n}…\sum\limits_{l_i=1}^{n}(gcd(l_1,l_2,…,l_i))^2
fn(i)=l1=1∑nl2=1∑n…li=1∑n(gcd(l1,l2,…,li))2
=
∑
d
=
1
n
d
2
∑
l
1
=
1
n
∑
l
2
=
1
n
…
∑
l
i
=
1
n
[
g
c
d
(
l
1
,
l
2
,
…
,
l
i
)
=
d
]
=\sum\limits_{d=1}^nd^2\sum\limits_{l_1=1}^{n}\sum\limits_{l_2=1}^{n}…\sum\limits_{l_i=1}^{n}[gcd(l_1,l_2,…,l_i)=d]
=d=1∑nd2l1=1∑nl2=1∑n…li=1∑n[gcd(l1,l2,…,li)=d]
=
∑
d
=
1
n
d
2
∑
l
1
=
1
n
d
∑
l
2
=
1
n
d
…
∑
l
i
=
1
n
d
[
g
c
d
(
l
1
,
l
2
,
…
,
l
i
)
=
1
]
=\sum\limits_{d=1}^nd^2\sum\limits_{l_1=1}^{\frac{n}{d}}\sum\limits_{l_2=1}^{\frac{n}{d}}…\sum\limits_{l_i=1}^{\frac{n}{d}}[gcd(l_1,l_2,…,l_i)=1]
=d=1∑nd2l1=1∑dnl2=1∑dn…li=1∑dn[gcd(l1,l2,…,li)=1]
=
∑
d
=
1
n
d
2
∑
l
1
=
1
n
d
∑
l
2
=
1
n
d
…
∑
l
i
=
1
n
d
∑
t
∣
g
c
d
(
l
1
,
l
2
,
…
,
l
i
)
μ
(
t
)
=\sum\limits_{d=1}^nd^2\sum\limits_{l_1=1}^{\frac{n}{d}}\sum\limits_{l_2=1}^{\frac{n}{d}}…\sum\limits_{l_i=1}^{\frac{n}{d}}\sum\limits_{t|gcd(l_1,l_2,…,l_i)}\mu(t)
=d=1∑nd2l1=1∑dnl2=1∑dn…li=1∑dnt∣gcd(l1,l2,…,li)∑μ(t)
=
∑
d
=
1
n
d
2
∑
t
=
1
n
d
μ
(
t
)
⌊
n
t
d
⌋
i
=\sum\limits_{d=1}^nd^2\sum\limits_{t=1}^{\frac{n}{d}} \mu(t){\lfloor \frac{n}{td}\rfloor}^i
=d=1∑nd2t=1∑dnμ(t)⌊tdn⌋i
=
∑
T
=
1
n
⌊
n
T
⌋
i
∑
d
∣
T
d
2
μ
(
T
d
)
=\sum\limits_{T=1}^n{\lfloor \frac{n}{T}\rfloor}^i\sum\limits_{d|T}d^2\mu(\frac{T}{d})
=T=1∑n⌊Tn⌋id∣T∑d2μ(dT)
∑
i
=
2
k
f
n
(
i
)
=
∑
i
=
2
k
∑
T
=
1
n
⌊
n
T
⌋
i
∑
d
∣
T
d
2
μ
(
T
d
)
\sum\limits_{i=2}^kf_n(i)=\sum\limits_{i=2}^k\sum\limits_{T=1}^n{\lfloor \frac{n}{T}\rfloor}^i\sum\limits_{d|T}d^2\mu(\frac{T}{d})
i=2∑kfn(i)=i=2∑kT=1∑n⌊Tn⌋id∣T∑d2μ(dT)
=
∑
T
=
1
n
∑
i
=
2
k
⌊
n
T
⌋
i
∑
d
∣
T
d
2
μ
(
T
d
)
=\sum\limits_{T=1}^n\sum\limits_{i=2}^k{\lfloor \frac{n}{T}\rfloor}^i\sum\limits_{d|T}d^2\mu(\frac{T}{d})
=T=1∑ni=2∑k⌊Tn⌋id∣T∑d2μ(dT)
记
f
=
∑
d
∣
T
d
2
μ
(
T
d
)
=
i
d
2
∗
μ
,
g
=
1
,
h
=
f
∗
g
=
i
d
2
f=\sum\limits_{d|T}d^2\mu(\frac{T}{d})=id^2*\mu,g=1,h=f*g=id^2
f=d∣T∑d2μ(dT)=id2∗μ,g=1,h=f∗g=id2
由于杜教筛公式:
g
(
1
)
S
(
n
)
=
∑
i
=
1
n
h
(
i
)
−
∑
d
=
2
n
g
(
d
)
S
(
⌊
n
d
⌋
)
g(1)S(n)=\sum\limits_{i=1}^{n}h(i)-\sum\limits_{d=2}^{n}g(d)S(\lfloor\frac{n}{d}\rfloor)
g(1)S(n)=i=1∑nh(i)−d=2∑ng(d)S(⌊dn⌋)
可以构造解决这个前缀和。
∑
i
=
2
k
⌊
n
T
⌋
i
\sum\limits_{i=2}^k{\lfloor \frac{n}{T}\rfloor}^i
i=2∑k⌊Tn⌋i,记
q
=
⌊
n
T
⌋
,
∑
i
=
2
k
⌊
n
T
⌋
i
=
q
2
(
q
k
−
1
−
1
)
q
−
1
q={\lfloor \frac{n}{T}\rfloor},\sum\limits_{i=2}^k{\lfloor \frac{n}{T}\rfloor}^i=\frac{q^2(q^{k-1}-1)}{q-1}
q=⌊Tn⌋,i=2∑k⌊Tn⌋i=q−1q2(qk−1−1)
然后按照
⌊
n
T
⌋
{\lfloor \frac{n}{T}\rfloor}
⌊Tn⌋整数分块就行了
对于
f
=
i
d
2
∗
μ
f=id^2*\mu
f=id2∗μ,需要预处理
1
e
6
1e6
1e6之内的前缀和,
两个积性函数卷积的线性筛法:
vis[1] = low[1] = 1; H[1] = 初始化
for(int i = 2; i <= N; i++) {
if(!vis[i]) prime[++tot] = i, mu[i] = -1, H[i] = 质数的情况, low[i] = i;
for(int j = 1; j <= tot && i * prime[j] <= N; j++) {
vis[i * prime[j]] = 1;
if(!(i % prime[j])) {
low[i * prime[j]] = (low[i] * prime[j]);
if(low[i] == i) H[i * prime[j]] = 特殊判断;
else H[i * prime[j]] = H[i / low[i]] * H[prime[j] * low[i]];
break;
}
H[i * prime[j]] = H[i] * H[prime[j]];
low[i * prime[j]] = prime[j];
}
}
#include<cstdio>
#include<map>
#include<cstring>
#define ll long long
using namespace std;
const int mod = 1e9+7;
const int maxn = 1e6+10;
bool vis[maxn];
map<int ,ll> mp;
ll low[maxn],H[maxn],sum[maxn];
int prime[maxn];
int tot,T;
char k[100010];
ll inv6;
ll f_g_sum(int n){
return (ll)n%mod*(n+1)%mod*(2*n+1)%mod*inv6%mod;
}
ll g_sum(int n){
return n%mod;
}
void f_sum(int n){
tot=0;
vis[1]=low[1]=1;
H[1]=1;
for(int i=2;i<=n;i++){
if(!vis[i]){
prime[++tot]=i;
H[i]=(i*i-1)%mod;
low[i]=i;
}
for(int j=1;j<=tot&&(ll)i*prime[j]<=n;j++){
vis[i*prime[j]]=1;
if(!(i%prime[j])){
low[i*prime[j]]=(low[i]*prime[j]);
if(low[i]==i)H[i*prime[j]]=(ll)prime[j]*prime[j]*H[i]%mod;
else H[i*prime[j]]=H[i/low[i]]*H[prime[j]*low[i]];
break;
}
H[i*prime[j]]=H[i]*H[prime[j]];
low[i*prime[j]]=prime[j];
}
}
sum[0]=0;
for(int i=1;i<=n;i++)
sum[i]=(sum[i-1]+H[i])%mod;
}
ll qpow(ll a,ll b){
ll res=1;
while(b){
if(b&1)res=res*a%mod;
a=a*a%mod;
b>>=1;
}
return res;
}
ll GetSum(int n){
if(n<=1000000)return sum[n];
if(mp[n]!=0)return mp[n];
ll ans = f_g_sum(n)%mod;
for(ll l = 2, r; l <= n; l = r + 1) {
r = (n / (n / l));
ans = (ans - (g_sum(r) - g_sum(l - 1)) * GetSum(n / l) + mod)%mod;
}
mp[n]=ans;
return ans;
}
ll inv(int n){
return qpow(n,mod-2);
}
int main(){
int n,m,len;
m=mod-1;
inv6=qpow(6,mod-2);
f_sum(1000000);
scanf("%d",&T);
while(T--){
scanf("%d%s",&n,k);
len=strlen(k);
int pow=0,K=0;
for(int i=0;i<len;i++){
pow=(int)(((ll)pow*10+k[i]-'0')%m);
K=(int)(((ll)K*10+k[i]-'0')%mod);
}
pow=(pow-1+m)%m;
K=(K-1+mod)%mod;
ll ans=0;
for(int l=1,r;l<=n;l=r+1){
r=n/(n/l);
ll q=n/l;
ll val;
if(q!=1)
val=q*q%mod*(qpow(q,pow)-1+mod)%mod*inv(q-1)%mod;
else val=K;
ans=(ans+(val*(GetSum(r)-GetSum(l-1)+mod)%mod)%mod)%mod;
}
printf("%lld\n",ans);
}
return 0;
}