51nod1238 最小公倍数之和 V3 莫比乌斯函数 杜教筛

题意:求\(\sum_{i = 1}^{n}\sum_{j = 1}^{n}lcm(i, j)\).
  题解:因为是用的莫比乌斯函数求的,所以推导比大部分题解多。。。而且我写式子一般都比较详细,所以可能看上去很多式子,实际上是因为每一步都写了,几乎没有跳过的。所以应该都可以看懂的。
  末尾的\(e\)函数是指的\(e[1] = 1\),\(e[x] = 0(x != 1)\)这样一个函数
  \[\sum_{i = 1}^{n}\sum_{j = 1}^{n}lcm(i, j)\]
  \[\sum_{i = 1}^{n} \sum_{i = 1}^{n} \frac{ij}{gcd(i, j)}\]
  枚举\(gcd\)
  \[\sum_{d = 1}^{n} \sum_{i = 1}^{\lfloor {\frac{n}{d}} \rfloor} \sum_{j = 1}^{\lfloor {\frac{n}{d}} \rfloor}[gcd(i, j) == d] \frac{ij}{d}\]
  因为\((\frac{ijd^2}{d} = ijd)\),所以:
  \[\sum_{d = 1}^{n} \sum_{i = 1}^{\lfloor {\frac{n}{d}} \rfloor} \sum_{j = 1}^{\lfloor {\frac{n}{d}} \rfloor}[gcd(i, j) == d] ijd\]
  \[\sum_{d = 1}^{n}d\sum_{i = 1}^{\lfloor {\frac{n}{d}} \rfloor} \sum_{j = 1}^{\lfloor {\frac{n}{d}} \rfloor}ij[gcd(i, j) == 1]\]
  \[\sum_{d = 1}^{n} d \sum_{i = 1}^{\lfloor {\frac{n}{d}} \rfloor} \sum_{j = 1}^{\lfloor {\frac{n}{d}} \rfloor} ij \sum_{k | gcd(i, j)} \mu(k)\]
  枚举k,再枚举k的倍数。
  \[\sum_{d = 1}^{n}d\sum_{k = 1}^{\lfloor {\frac{n}{d}} \rfloor}\mu(k) \sum_{i = 1}^{\lfloor {\frac{n}{dk}} \rfloor}ik \sum_{j = 1}^{\lfloor {\frac{n}{dk}} \rfloor}jk\]
  设\(S(n) = \sum_{i = 1}^{n}i\)
  \[\sum_{d = 1}^{n}d \sum_{k = 1}^{\lfloor {\frac{n}{d}} \rfloor} \mu(k) k ^ 2 S(\frac{n}{dk})\]
  枚举\(T = dk\)
  \[\sum_{T = 1}^{n} S(\frac{n}{T})^ 2 \sum_{k | T} \mu(k) k ^ 2 \frac{T}{k}\]
  \[\sum_{T = 1}^{n} S(\frac{n}{T})^ 2 \sum_{k | T} \mu(k) kT\]
  \[\sum_{T = 1}^{n} S(\frac{n}{k})^ 2 \cdot T \sum_{k | T} \mu(k)k\]
  设\(f(T) = T\sum_{k | T} \mu(k) k\),卷上\(id^2\),因为\(S(\frac{n}{k})\)可以数论分块,所以我们只需要快速求出区间\([l, r]\)内的\(f\)之和即可,显然求出\(f\)的前缀和即可解决问题
  \[(f * id^2)(n) = \sum_{i |n}f(i) \frac{n^2}{i^2}=\sum_{i | n}i \sum_{k | i} \mu(k) k \frac{n ^ 2}{i ^ 2}\]
  \[\sum_{i | n}\sum_{k | i} \mu(k)k\frac{n ^ 2}{i} = n \sum_{i | n}\sum_{k | i} \mu(k) k \frac{n}{i}\]
  设\[h(i) = \sum_{k | i} \mu(k)k\],则原式:
  \[n \sum_{i | n} h(i) \frac{n}{i} = n (h * id)(n)\]
  \[(f * id ^ 2)(n) = n (h * id)(n)\]
  \[h(n) = \sum_{k | n}\mu(k)k = (\mu \cdot id) * 1\]
  \[f * id ^ 2 = n [(\mu \cdot id) * 1 * id] = n[(\mu \cdot id) * id * 1]\]
  其中\[(\mu \cdot id) * id = \sum_{i | n} \mu(i) i \frac{n}{i} = n \sum_{i | n}\mu(i) = e\]
  所以
  \[n[(\mu \cdot id) * id * 1] = n[e * 1] = n\]
  带入杜教筛的式子:
  \[g(1)S(n) = \sum_{i = 1}^{n} (f * g)(i) - \sum_{i = 2}^{n}g(i)S(\frac{n}{i})\]
  \[= \sum_{i = 1}^{n}i - \sum_{i = 2}^{n}i ^ 2 S(\frac{n}{i})\]
  然后直接上杜教就可以了.
  其实还有一个问题。。。一开始预处理的前缀和怎么求?
  要知道前缀和,首先要求出\(f\).
  因为\(f(T) = T\sum_{k | T} \mu(k) k\),所以如果我们可以快速求出\(\sum_{k | T}\mu(k)k\),然后就只需要再\(O(n)\)的乘上\(T\)就可以了.
  我们先预处理出\(\mu(k)\),然后对于每一个\(k\),枚举它的倍数,统计贡献。那么复杂度为 \(\frac{n}{1} + \frac{n}{2} + ... + \frac{n}{n} = nlogn\)(此处的\(n\)为原题面的\(\frac{2}{3}\)次方,即要预处理的\(f\)个数)

#include<bits/stdc++.h>
using namespace std;
#define R register int
#define LL long long
#define RL register LL
#define AC 3000
#define ac 5000000
#define p 1000000007LL
//#define h(x) ((x <= block) ? sum[x] : S[n / x])

LL n, ans, block;
LL mu[ac], S[AC], sum[ac], inv[AC];
int pri[ac], tot;
bool z[ac], vis[AC];

inline LL h(LL x)
{
    return ((x <= block) ? sum[x] : S[n / x]);
}

inline void up(LL & a, LL b)
{
    a += b;
    if(a >= p) a -= p;
    if(a <= -p) a += p;
}

LL count(LL l, LL r){
    return (r - l + 1) % p * ((r + l) % p) % p * inv[2] % p;
}

void pre()
{
    scanf("%lld", &n), block = pow(n, 0.66666);
    mu[1] = 1;
    for(R i = 2; i <= block; i ++)
    {
        if(!z[i]) pri[++ tot] = i, mu[i] = -1;
        for(R j = 1; j <= tot; j ++)
        {
            int now = pri[j];
            if(i * now > block) break;
            z[i * now] = true;
            if(!(i % now)) break;
            mu[i * now] = - mu[i];
        }
    }
    inv[1] = 1;
    for(R i = 2; i <= 10; i ++) inv[i] = (p - p / i) * inv[p % i] % p;
    for(R i = 1; i <= block; i ++)//枚举mu(i)
        for(R j = 1; j; j ++)//枚举i的倍数
        {
            if(j * i > block) break;
            up(sum[i * j], mu[i] * i % p);
        }
    for(R i = 1; i <= block; i ++) sum[i] = sum[i] * i % p;
    for(R i = 1; i <= block; i ++) up(sum[i], sum[i - 1]);//算出f数组后还要统计前缀和
}

LL get(LL x)
{
    x %= p;
    return x * (x + 1) % p * (2 * x + 1) % p * inv[6] % p;
}

void cal(LL x)
{
    if(x <= block || vis[n / x]) return ;
    LL rnt = count(1, x);
    for(RL i = 2, lim, now; i <= x; i = lim + 1)
    {
        lim = x / (x / i), now = x / i, cal(now);
        up(rnt, - ((get(lim) - get(i - 1)) % p * h(now) % p));
    }
    S[n / x] = rnt, vis[n / x] = true;
}

void work()
{
    for(RL i = 1, lim, now, x; i <= n; i = lim + 1)
    {
        lim = n / (n / i), now = n / i, x = count(1, now);
        up(ans, (x % p * x % p * ((h(lim) - h(i - 1)) % p) % p));
    }
    printf("%lld\n", (ans + p) % p);
}

int main()
{
    //freopen("in.in", "r", stdin);
    pre();
    cal(n);
    work();
//  fclose(stdin);
    return 0;
}

原文地址:https://www.cnblogs.com/ww3113306/p/10166573.html

时间: 2024-10-20 16:19:44

51nod1238 最小公倍数之和 V3 莫比乌斯函数 杜教筛的相关文章

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

题意 求$\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} $$ 利用

【bzoj4176】Lucas的数论 莫比乌斯反演+杜教筛

题目描述 去年的Lucas非常喜欢数论题,但是一年以后的Lucas却不那么喜欢了. 在整理以前的试题时,发现了这样一道题目“求Sigma(f(i)),其中1<=i<=N”,其中 表示i的约数个数.他现在长大了,题目也变难了. 求如下表达式的值: 其中f(ij)表示ij的约数个数. 他发现答案有点大,只需要输出模1000000007的值. 输入 第一行一个整数n. 输出 一行一个整数ans,表示答案模1000000007的值. 样例输入 2 样例输出 8 题解 莫比乌斯反演+杜教筛 首先有个神奇

51nod1238. 最小公倍数之和 V3(莫比乌斯反演)

题目链接 https://www.51nod.com/Challenge/Problem.html#!#problemId=1238 题解 本来想做个杜教筛板子题结果用另一种方法过了...... 所谓的"另一种方法"用到的技巧还是挺不错的,因此这里简单介绍一下. 首先还是基本的推式子: \[\begin{aligned}\sum_{i = 1}^n \sum_{j = 1}^n {\rm lcm}(i, j) &= \sum_{i = 1}^n \sum_{j = 1}^n \

数论入门——莫比乌斯函数,欧拉函数,狄利克雷卷积,线性筛,莫比乌斯反演,杜教筛

一个菜鸡对数论的一点点理解... 莫比乌斯函数 定义函数\(\mu(n)\)为: 当n有平方因子时,\(\mu(n)=0\). 当n没有平方因子时,\(\mu(n)=(-1)^{\omega(n)}\),\(\omega(n)\)表示n不同质因子的个数. 性质1: \(\sum_{d|n}\mu(d)=[n=1]\) 证明:我们把n分解质因数,则原式\(=(-1+1)^{\omega(n)}=0\). 因为对于不同的质因子,只有选和不选两种方案,这是一个组合数相加的形式,偶数加奇数减,根据二项式

莫比乌斯反演欧拉函数杜教筛大总结

莫比乌斯函数 定义 设\(n=\prod_{i=1}^{k} p_i^{c_i}\),则\(\mu(n)=(-1)^k\),特别地\(\mu(1)=1\). 性质 最常用性质 \(\sum_{d|n}\mu(d)=[n=1]\) 反演性质 \(F(n)=\sum_{d|n}f(d) \Longleftrightarrow f(n)=\sum_{d|n}F(d)\mu(\frac{n}{d})\) \(F(n)=\sum_{n|d}f(d) \Longleftrightarrow f(n)=\su

[51nod1227]平均最小公倍数(莫比乌斯反演+杜教筛)

题意 求 $\sum_{i=a}^b \sum_{j=1}^i \frac{lcm(i,j)}{i}$. 分析 只需要求出前缀和, $$\begin{aligned}\sum_{i=1}^n \sum_{j=1}^i \frac{lcm(i,j)}{i} &= \sum_{i=1}^n \sum_{j=1}^i \frac{j}{gcd(i,j)} \\&= \sum_{d=1}^n \sum _{i=1}^n \sum_{j=1}^i \frac{j}{d} \cdot [gcd(i,j

EOJ Monthly 2019.11 E. 数学题(莫比乌斯反演+杜教筛+拉格朗日插值)

传送门 题意: 统计\(k\)元组个数\((a_1,a_2,\cdots,a_n),1\leq a_i\leq n\)使得\(gcd(a_1,a_2,\cdots,a_k,n)=1\). 定义\(f(n,k)\)为满足要求的\(k\)元组个数,现在要求出\(\sum_{i=1}^n f(i,k),1\leq n\leq 10^9,1\leq k\leq 1000\). 思路: 首先来化简一下式子,题目要求的就是: \[ \begin{aligned} &\sum_{i=1}^n\sum_{j=1

luogu3172 [CQOI2015]选数 莫比乌斯反演+杜教筛

link 题目大意:有N个数,每个数都在区间[L,H]之间,请求出所有数的gcd恰好为K的方案数 推式子 首先可以把[L,H]之间的数字gcd恰好为K转化为[(L-1)/K+1,H/K]之间数字gcd恰好为1 然后就可以反演了 下面手误把所有的H都打成了R \(\sum_{i_1=L}^R\sum_{i_2=L}^R\dots\sum_{i_N=L}^R[\gcd(i_1,i_2,\dots,i_N)=1]\) \(\sum_{i_1=L}^R\sum_{i_2=L}^R\dots\sum_{i

莫比乌斯函数之和 51Nod - 1244 (杜教筛)

莫比乌斯函数之和 51Nod - 1244 题意: