BZOJ 4407 于神之怒加强版 莫比乌斯反演,线性筛
BZOJ 4407 于神之怒加强版 莫比乌斯反演,线性筛
题意
给定\(n,m,k\),求
\[\sum_{i = 1}^{n}\sum_{j = 1}^{m}gcd(i,j)^k mod(1e9 + 7)
\]
\[1\leq T \leq 2000\\
1\leq n,m,k \leq 5e6
\]
分析
\[\sum \sum (i,j)^k \\
= \sum_d \sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}\sum_{j = 1}^{\lfloor\frac{m}{d}\rfloor}[(i,j) = 1]\\
= \sum_dd^k \sum_u \mu(u) \lfloor\frac{n}{du}\rfloor\lfloor\frac{m}{du}\rfloor\\
= \sum_D\lfloor\frac{n}{D}\rfloor\lfloor\frac{m}{D}\rfloor\sum_{d|D}d^{k}\mu(\frac{D}{d})
\]
发现后面那坨是积性函数乘积性函数,且\(tmp = p ^ a\)时,\(f[tmp] = tmp^k - p^{(a - 1){k}}\),可以在\(log\)时间算出
于是线性筛即可
ll f[maxn];
int prime[maxn];
int vis[maxn];
ll last[maxn];
int n, m, k;
void init() {
f[1] = 1;
int cnt = 0;
for (int i = 2; i < maxn; i++) {
if (!vis[i]) {
prime[cnt++] = last[i] = i, f[i] = (ksm(i, k ,MOD) - 1 + MOD) % MOD;
}
for (int j = 0; j < cnt && i * prime[j] < maxn; j++) {
int tmp = i * prime[j];
vis[tmp] = 1;
if (i % prime[j] == 0) {
last[tmp] = last[i] * prime[j];
if (tmp != last[tmp])
f[tmp] = f[i / last[i]] * f[last[tmp]] % MOD;
else
f[tmp] = (ksm(tmp, k,MOD) - ksm(i, k,MOD) + MOD) % MOD;
break;
}
else {
last[tmp] = prime[j];
f[tmp] = f[i] * f[prime[j]] % MOD;
}
}
}
for (int i = 2; i < maxn; i++)
f[i] = f[i] + f[i - 1], f[i] %= MOD;
}
int main() {
int T = readint();
k = readint();
init();
while (T--) {
n = readint();
m = readint();
ll res = 0;
for (int l = 1,r; l <= n && l <= m; l = r + 1) {
r = min(n / (n / l), m / (m / l));
res += (f[r] - f[l -1] + MOD)* (n / l) % MOD* (m / l) % MOD;
res %= MOD;
}
printf("%lld\n", res);
}
}