题意
设f(n)=∑d∣n∣μ(d)∣\displaystyle f(n)=\sum_{d\mid n}|\mu(d)|f(n)=d∣n∑∣μ(d)∣
求∑i=1mf(ni)mod 109+7\displaystyle\sum_{i=1}^mf(ni)\mod 10^9+7i=1∑mf(ni)mod109+7
1≤n,m≤1071\le n,m\le10^71≤n,m≤107
题解
设w(n)w(n)w(n)表示nnn的质因子个数,根据μ\muμ的定义,有
f(n)=∑k=0w(n)(w(n)k)∣(−1)k∣=2w(n) \displaystyle f(n)=\sum_{k=0}^{w(n)}{w(n)\choose k}|(-1)^k|=2^{w(n)} f(n)=k=0∑w(n)(kw(n))∣(−1)k∣=2w(n)
显然f(n)f(n)f(n)是一个积性函数,且满足f(ab)=f(a)f(b)f(gcd(a,b))\displaystyle f(ab)=\frac{f(a)f(b)}{f(\gcd(a,b))}f(ab)=f(gcd(a,b))f(a)f(b)。
化简原式:
∑i=1mf(in)=f(n)∑i=1mf(i)f(gcd(n,i))=f(n)∑d∣n1f(d)∑i=1mf(i)[gcd(i,n)=d]=f(n)∑d∣n1f(d)∑i=1⌊md⌋f(id)[gcd(i,nd)=1]=f(n)∑d∣n1f(d)∑i=1⌊md⌋f(id)∑p∣i,p∣ndμ(p)=f(n)∑d∣n∑pd∣nμ(p)f(d)∑i=1⌊mpd⌋f(ipd)=f(n)∑T∣n∑d∣Tμ(Td)f(d)∑i=1⌊mT⌋f(iT)=f(n)∑T∣ng(T)∑i=1⌊mT⌋f(iT)
\begin{aligned}
\sum_{i=1}^mf(in)=&f(n)\sum_{i=1}^m\frac{f(i)}{f(\gcd(n,i))}\\
&=f(n)\sum_{d\mid n}\frac1{f(d)}\sum_{i=1}^mf(i)[\gcd(i,n)=d]\\
&=f(n)\sum_{d\mid n}\frac1{f(d)}\sum_{i=1}^{\lfloor\frac md\rfloor}f(id)[\gcd(i,\frac nd)=1]\\
&=f(n)\sum_{d\mid n}\frac1{f(d)}\sum_{i=1}^{\lfloor\frac md\rfloor}f(id)\sum_{p|i,p|\frac nd}\mu(p)\\
&=f(n)\sum_{d\mid n}\sum_{pd\mid n}\frac{\mu(p)}{f(d)}\sum_{i=1}^{\lfloor\frac m{pd}\rfloor}f(ipd)\\
&=f(n)\sum_{T\mid n}\sum_{d\mid T}\frac{\mu(\frac Td)}{f(d)}\sum_{i=1}^{\lfloor\frac mT\rfloor}f(iT)\\
&=f(n)\sum_{T\mid n}g(T)\sum_{i=1}^{\lfloor\frac mT\rfloor}f(iT)
\end{aligned}
i=1∑mf(in)=f(n)i=1∑mf(gcd(n,i))f(i)=f(n)d∣n∑f(d)1i=1∑mf(i)[gcd(i,n)=d]=f(n)d∣n∑f(d)1i=1∑⌊dm⌋f(id)[gcd(i,dn)=1]=f(n)d∣n∑f(d)1i=1∑⌊dm⌋f(id)p∣i,p∣dn∑μ(p)=f(n)d∣n∑pd∣n∑f(d)μ(p)i=1∑⌊pdm⌋f(ipd)=f(n)T∣n∑d∣T∑f(d)μ(dT)i=1∑⌊Tm⌋f(iT)=f(n)T∣n∑g(T)i=1∑⌊Tm⌋f(iT)
其中g(T)=∑d∣Tμ(Td)f(d)\displaystyle g(T)=\sum_{d\mid T}\frac{\mu(\frac Td)}{f(d)}g(T)=d∣T∑f(d)μ(dT),即g=1f×μ\displaystyle g=\frac1f\times \mug=f1×μ,也是一个积性函数,用线性筛的方法推导可得:
g(T)={(−12)w(T),T=∏i=1w(T)pi0,otherwise g(T)=\left\{\begin{aligned} \Big(-\frac12\Big)^{w(T)},&&T=\prod_{i=1}^{w(T)} p_i\\ 0,&&{\rm otherwise} \end{aligned}\right. g(T)=⎩⎪⎪⎨⎪⎪⎧(−21)w(T),0,T=i=1∏w(T)piotherwise
也就是说对于T∣nT\mid nT∣n的g(T)g(T)g(T),只有当TTT是nnn的质因子集合的某个子集中所有元素的乘积时,才会产生贡献。而n≤107n\le10^7n≤107时,w(n)≤8w(n)\le8w(n)≤8,故可以在O(8⋅28)O(8\cdot2^8)O(8⋅28)的时间内枚举出所有有贡献的TTT,这样比直接枚举约数要快一些。
由于内存限制,∑i=1⌊mT⌋f(iT)\displaystyle \sum_{i=1}^{\lfloor\frac mT\rfloor}f(iT)i=1∑⌊Tm⌋f(iT)不能预处理。
考虑离线,把所有∑i=1⌊mT⌋f(iT)\displaystyle \sum_{i=1}^{\lfloor\frac mT\rfloor}f(iT)i=1∑⌊Tm⌋f(iT)的询问,按TTT为第一关键字,⌊mT⌋\lfloor\frac mT\rfloor⌊Tm⌋为第二关键字排序然后暴力计算即可。
计算答案时注意要乘上f(n)g(T)f(n)g(T)f(n)g(T)的系数。
时间复杂度O(nlogn+T(n+8⋅28))O(n\log n+T(\sqrt n+8\cdot 2^8))O(nlogn+T(n+8⋅28))
#include <bits/stdc++.h>
using namespace std;
const int N = 1e7 + 5, P = 1e9 + 7, Inv2 = (P + 1) / 2;
typedef long long ll;
struct Data {
int d, m, w, id;
};
int n, m, q, Ans[10005];
int is[N], prime[N], f[N], g[N];
vector<Data> Q;
int main() {
n = 1e7;
f[1] = g[1] = 1;
for (int i = 2; i <= n; ++i) {
if (!is[i])
prime[++prime[0]] = i, f[i] = 2, g[i] = P - Inv2;
for (int j = 1, x; j <= prime[0] && (x = i * prime[j]) <= n; ++j) {
is[x] = 1;
if (i % prime[j])
f[x] = 2 * f[i] % P, g[x] = (ll)g[prime[j]] * g[i] % P;
else {
f[x] = f[i];
break;
}
}
}
scanf("%d", &q);
for (int T = 1; T <= q; ++T) {
scanf("%d%d", &n, &m);
int t = n;
vector<int> div;
for (int d = 2; d * d <= t; ++d)
if (t % d == 0) {
div.push_back(d);
while (t % d == 0)
t /= d;
}
if (t != 1)
div.push_back(t);
for (int s = 0; s < (1 << div.size()); ++s) {
int d = 1;
for (int i = 0; i <= (int)div.size() - 1; ++i)
if (s & (1 << i))
d *= div[i];
if (m < d || !g[d])
continue;
Q.push_back({d, (m / d) * d, int((ll)f[n] * g[d] % P), T});
}
}
sort(Q.begin(), Q.end(),
[](Data a, Data b) { return a.d == b.d ? a.m < b.m : a.d < b.d; });
ll w;
int d = 0, i;
for (auto t : Q) {
if (t.d != d)
d = i = t.d, w = 0;
for (; i <= t.m; i += d)
w += f[i];
Ans[t.id] = (Ans[t.id] + (ll)t.w * (w %= P) % P) % P;
}
for (int i = 1; i <= q; ++i)
printf("%d\n", Ans[i]);
return 0;
}