码迷,mamicode.com
首页 > 其他好文 > 详细

【51Nod 1237】最大公约数之和 V3 莫比乌斯反演+杜教筛

时间:2017-11-15 17:14:10      阅读:226      评论:0      收藏:0      [点我收藏+]

标签: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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!