标签:floor bool ash name 公约数 red prim turn set
求$\sum_{i=1}^{n}\sum_{j=1}^{n}(i,j)$
枚举约数
$$
\begin{align}
ans &=\sum_{d=1}^{n}\sum_{i=1}^{n}\sum_{j=1}^{n}[(i,j)=d] \
&=\sum_{d=1}^{n}\sum_{i=1}^{\lfloor \frac{n}{d} \rfloor}\sum_{j=1}^{\lfloor \frac{n}{d} \rfloor}[(i,j)=1] \
\end{align}
$$
利用莫比乌斯反演,$\sum_{d|n}\mu(d)=[n=1]$
$$
\begin{align}
ans &=\sum_{d=1}^{n}\sum_{i=1}^{\lfloor \frac{n}{d} \rfloor}\sum_{j=1}^{\lfloor \frac{n}{d} \rfloor}\sum_{k|gcd(i,j)}\mu(k) \
&= \sum_{d=1}^{n}d\sum_{k=1}^{n}\mu(k)\sum_{i=1}^{\lfloor \frac{n}{d} \rfloor}\sum_{j=1}^{\lfloor \frac{n}{d} \rfloor} \
&= \sum_{d=1}^{n}d\sum_{k=1}^{n}\mu(k) \lfloor \frac{n}{dk} \rfloor \lfloor \frac{n}{dk} \rfloor
\end{align}
$$
令$T=dk$
$$
\begin{align}
ans &= \sum_{d=1}^{n}d\sum_{k=1}^{n}\mu(k) \lfloor \frac{n}{dk} \rfloor \lfloor \frac{n}{dk} \rfloor \
&= \sum_{T=1}^{n}\sum_{d|T}d\mu(\frac{T}{d})\lfloor \frac{n}{T} \rfloor \lfloor \frac{n}{T} \rfloor
\end{align}
$$
因为$\sum_{d|n}d\mu(\frac{n}{d})=id * \mu,id=\phi * I$,所以$id * \mu = \phi$
$$
\begin{align}
ans &= \sum_{T=1}^{n}\phi(T)\lfloor \frac{n}{T} \rfloor \lfloor \frac{n}{T} \rfloor
\end{align}
$$
利用杜教筛处理出$\phi$前缀和,分块计算
时间复杂度$O(n^{\frac{2}{3}})$
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL MAXN = 4641588;
const LL MOD = 1e9 + 7, Inv = 500000004;
LL phi[MAXN + 10], prime[MAXN + 10], tot;
bool check[MAXN + 10];
void Shaker() {
memset(check, 0, sizeof(check));
phi[1] = 1; tot = 0;
for(LL i = 2; i <= MAXN; ++i) {
if(!check[i]) prime[tot++] = i, phi[i] = i - 1;
for(LL j = 0; j < tot; ++j) {
if(i * prime[j] > MAXN) break;
check[i * prime[j]] = 1;
if(i % prime[j] == 0) {phi[i * prime[j]] = phi[i] * prime[j]; break;}
else phi[i * prime[j]] = phi[i] * (prime[j] - 1);
}
}
for(LL i = 2; i <= MAXN; ++i) phi[i] = (phi[i] + phi[i - 1]) % MOD;
}
unordered_map<LL, LL> Hash;
LL CalPhi(LL n) {
if(n <= MAXN) return phi[n];
if(Hash[n]) return Hash[n];
LL res = ((n % MOD * (n % MOD + 1) % MOD) % MOD * Inv % MOD) % MOD, r, tmp = 0;
for(LL i = 2; i <= n; i = r + 1) {
r = n / (n / i);
tmp = (tmp + ((r - i + 1) % MOD * CalPhi(n / i) % MOD) % MOD) % MOD;
}
res = (res - tmp + MOD) % MOD;
return Hash[n] = res;
}
LL Solve(LL n) {
LL res = 0, r = 0;
for(LL i = 1; i <= n; i = r + 1) {
r = n / (n / i);
res = (res + (((n / i) % MOD) * ((n / i) % MOD) % MOD * (CalPhi(r) - CalPhi(i - 1) + MOD) % MOD) % MOD) % MOD;
}
return res;
}
LL x;
int main() {
Shaker();
cin >> x;
cout << Solve(x) << endl;
return 0;
}
【51Nod 1237】最大公约数之和 V3 莫比乌斯反演+杜教筛
标签:floor bool ash name 公约数 red prim turn set
原文地址:http://www.cnblogs.com/ogiso-setsuna/p/7839568.html