BZOJ 4407 于神之怒加强版 莫比乌斯反演,线性筛
题意
给定(n,m,k),求
[sum_{i = 1}^{n}sum_{j = 1}^{m}gcd(i,j)^k mod(1e9 + 7)
]
[1leq T leq 2000\
1leq n,m,k leq 5e6
]
分析
[sum sum (i,j)^k \
= sum_d sum_{i=1}^{lfloorfrac{n}{d}
floor}sum_{j = 1}^{lfloorfrac{m}{d}
floor}[(i,j) = 1]\
= sum_dd^k sum_u mu(u) lfloorfrac{n}{du}
floorlfloorfrac{m}{du}
floor\
= sum_Dlfloorfrac{n}{D}
floorlfloorfrac{m}{D}
floorsum_{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
", res);
}
}