P1829 [国家集训队]Crash的数字表格

原题传送门

前置芝士

莫比乌斯反演

乘法逆元

数论分块

正文

//补充:以下式子中的除法均为整除

由题目可以得知,这道题让我们所求的数,用一个式子来表达即为:\(\boxed{ANS=\sum_{i=1}^n \sum_{j=1}^m LCM(i,j)}\)

而根据莫比乌斯反演的内容,我们可以对右边的式子进行进一步的推导:

\[\begin{align}
\sum_{i=1}^n \sum_{j=1}^m LCM(i,j)&=\sum_{i=1}^n \sum_{j=1}^m {ij\over gcd(i,j)}\\
&=\sum_{t=1}^n t \sum_{i=1}^n \sum_{j=1}^m {ij \over {t^2}} [GCD({i\over t},{j \over t})=1]\\
&=\sum_{t=1}^n t \sum_{i=1}^{n\over t} \sum_{j=1}^{m \over t} ij[GCD(i,j)=1]\\
&=\sum_{t=1}^n t f({n\over t},{m\over t})

\end{align}
\]

接下来,令 \(\boxed{K=td}\) ,则有以下推论:

\[\begin{align}
\sum_{t=1}^n t \sum_{d=1}^{n\over t} d^2 \mu(d) *{((1+{n\over td}){n\over td})\over 2}*{((1+{m\over td}){m\over td})\over 2}&=\sum_{K=1}^n *{((1+{n\over td}){n\over td})\over 2}*{((1+{m\over td}){m\over td})\over 2} \sum_{d|K} d^2 \mu(d) {K\over d}\\

\end{align}
\]

然后,我们有定义一个函数:\(\boxed{g(K)=\sum_{d|K} K d \mu (d)}\),则有:

\[\begin{align}
g(K)&=\sum_{d|K} K d \mu (d)\\
&=K \sum_{d|K} \mu(d) d\\
&=K f(K)\\
\end{align}
\]

这里我们定义了一个函数:\(f\),其性质为:

\[f(K)=\sum_{d|K} \mu(d)d\\
\]

我们可以立马发现函数 \(f\) 是一个积性函数,若我们设 \(p\) 为一个质数,则会有以下推论:

\[f(p)=1-p\\
f(p^K)=1-p\\
而当K\ge 2 时,有:f(p^K)=f(p^{K-1})
\]

最终,我们便可以通过预处理函数 \(f\) ,从而更快地得到答案。但我们该如何预处理函数 \(f\) 呢?很简单,我们只需要用线性筛处理即可。

请仔细回想一下欧拉函数线性筛莫比乌斯函数线性筛是如何由普通的线性筛转化而来的,若读者已经完全理解了这两种线性筛的拓展应用,那么对于函数 \(f\) 的线性筛求法,想必读者也能轻易写出。这里将不会对函数 \(f\) 的预处理做过多的介绍。

代码如下:

typedef long long ll;
const int N=10000005;
int tot,phi[N],f[N],prime[N];
ll pre[N];
bool np[N];
void init(int n){
np[1]=true;
f[1]=1;
for (int i=2;i<=n;i++){
if (!np[i]){
prime[tot++]=i;
f[i]=1-i;
}
for (int j=0,k;(k=i*prime[j])<=n;j++){
np[k]=true;
if (i%prime[j]==0) {
f[k]=f[i];
break;
}
f[k]=f[i]*f[prime[j]];
}
}
}

现在我们已经完成了 (且时间复杂度为\(O (n)\) )对函数 \(f\) 的预处理,接下来便是计算答案了。不过,先别着急,我们再来看一看推导后的式子:

\[\sum_{K=1}^n *{((1+{n\over td}){n\over td})\over 2}*{((1+{m\over td}){m\over td})\over 2} \sum_{d|K} d^2 \mu(d) {K\over d}
\]

是不是发现了一个惊喜?相信读者在学习完数论分块的内容后会很容易地发现:这个式子是可以通过数论分块进行进一步优化的。接下来,我们将对这一步的优化进行解释:

既然我们定义了函数 \(g\) ,我们先把 \(g\) 带进上面的式子。

\[\sum_{K=1}^n *{((1+{n\over td}){n\over td})\over 2}*{((1+{m\over td}){m\over td})\over 2} * g(K)
\]

接着,因为我们已经预处理完了函数 \(f\) ,那么便可以用 \(f\) 来表示 \(g\) 。

\[g(K)=f(K)*K
\]

现在已经很明显了:我们可以对这个\(g(K)\)进行数论分块的优化。我们只需算出前缀和,就可以为所欲为愉快地数论分块了。

这里定义前缀和为数组 \(pre\) ,则转移方程为:\(\boxed{pre[i]=pre[i-1]+f[i]*i}\)

最后,在结合乘法逆元的知识(因为题目给定了模数:\(20101009\) ,且式中带有除法),便可以在不超时的情况下计算出答案。

最终的代码如下:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=10000005;
const ll mod=20101009;
int tot,f[N],prime[N];//质数个数+1,第i个f函数的值,第i个质数
ll pre[N];//前缀和
bool np[N];//非质数
void init(int n){
np[1]=true;
f[1]=1;
for (int i=2;i<=n;i++){
if (!np[i]){
prime[tot++]=i;
f[i]=1-i;
}
for (int j=0,k;(k=i*prime[j])<=n;j++){
np[k]=true;
if (i%prime[j]==0) {
f[k]=f[i];
break;
}
f[k]=f[i]*f[prime[j]];
}
}
for (int i=1;i<=n;i++) pre[i]=pre[i-1]+(ll)f[i]*i;//处理前缀和
}//预处理
int main(){
int n,m;
ll ans=0;//最终答案
scanf("%d %d",&n,&m);
if (n>m) swap(n,m);//保证n比m小
init(n);
int j;
for (int i=1;i<=n;i=j+1){
j=min(n/(n/i),m/(m/i));//开始愉悦地数论分块~~
ll a1=(ll)(1+n/i)*(n/i)/2%mod,a2=(ll)(1+m/i)*(m/i)/2%mod;//一定记得加(long long)
ans+=(a1%mod*a2%mod*(pre[j]-pre[i-1])%mod+mod)%mod;
ans%=mod;
//乘法逆元的运用
}
printf("%lld\n",ans%mod);
return 0;
}

最后的题外话:作者一定会想方设法地把莫比乌斯函数的博客更新完的(哭,太难了)。

感谢阅读。

(作者的OI历程:)

P1829 [国家集训队]Crash的数字表格的更多相关文章

  1. [Luogu P1829] [国家集训队]Crash的数字表格 / JZPTAB (莫比乌斯反演)

    题面 传送门:洛咕 Solution 调到自闭,我好菜啊 为了方便讨论,以下式子\(m>=n\) 为了方便书写,以下式子中的除号均为向下取整 我们来颓柿子吧qwq 显然,题目让我们求: \(\l ...

  2. 洛谷 P1829 [国家集训队]Crash的数字表格 / JZPTAB 解题报告

    [国家集训队]Crash的数字表格 / JZPTAB 题意 求\(\sum\limits_{i=1}^n\sum\limits_{j=1}^mlcm(i,j)\),\(n,m\le 10^7\) 鉴于 ...

  3. 洛谷P1829 [国家集训队]Crash的数字表格 / JZPTAB(莫比乌斯反演)

    题目背景 提示:原 P1829 半数集问题 已经迁移至 P1028 数的计算 题目描述 今天的数学课上,Crash小朋友学习了最小公倍数(Least Common Multiple).对于两个正整数a ...

  4. 洛谷P1829 [国家集训队]Crash的数字表格

    题目描述 今天的数学课上,Crash小朋友学习了最小公倍数(Least Common Multiple).对于两个正整数a和b,LCM(a, b)表示能同时整除a和b的最小正整数.例如,LCM(6, ...

  5. P1829 [国家集训队]Crash的数字表格 / JZPTAB

    推式子太快乐啦!虽然我好蠢而且dummy和maomao好巨(划掉) 思路 莫比乌斯反演的题目 首先这题有\(O(\sqrt n)\)的做法但是我没写咕咕咕 然后就是爆推一波式子 \[ \sum_{i= ...

  6. 洛谷P1829 [国家集训队]Crash的数字表格 / JZPTAB(莫比乌斯反演)

    传送门 式子好麻烦orz……大佬好腻害orz->这里 //minamoto #include<iostream> #include<cstdio> #define ll ...

  7. P1829 [国家集训队]Crash的数字表格 / JZPTAB 莫比乌斯反演

    又一道...分数和取模次数成正比$qwq$ 求:$\sum_{i=1}^N\sum_{j=1}^Mlcm(i,j)$ 原式 $=\sum_{i=1}^N\sum_{j=1}^M\frac{i*j}{g ...

  8. 洛谷 P1829 [国家集训队]Crash的数字表格 / JZPTAB(莫比乌斯反演)

    题意:求$\sum_{i=1}^{n}\sum_{j=1}^{m}lcm(i,j)$. 开始开心(自闭)化简: $\sum_{i=1}^{n}\sum_{j=1}^{m}lcm(i,j)$ =$\su ...

  9. 题解-[国家集训队]Crash的数字表格 / JZPTAB

    题解-[国家集训队]Crash的数字表格 / JZPTAB 前置知识: 莫比乌斯反演 </> [国家集训队]Crash的数字表格 / JZPTAB 单组测试数据,给定 \(n,m\) ,求 ...

随机推荐

  1. WannaRen来袭:螣龙安科带你盘点那些年的勒索病毒

    2020年4月7日,360CERT监测发现网络上出现一款新型勒索病毒wannaRen,该勒索病毒会加密windows系统中几乎所有的文件,并且以.WannaRen作为后缀.360CERT该事件评定:危 ...

  2. 「一本通 1.1 例 4」加工生产调度(贪心算法)(luogu P1248)题解

    加工生产调度 题目描述 某工厂收到了 n n n 个产品的订单,这 n n n 个产品分别在 A.B 两个车间加工,并且必须先在 A 车间加工后才可以到 B 车间加工. 某个产品 i i i 在 A. ...

  3. stringstrean类中关于clear和str的比较

    stringstream类涉及到多次类型转换的时候容易出现异常错误 因为第一次数据如果读入eof或者输出完整来到eof,此时stringstream会自动为其添上eofbit标志位,此时继续进行任何操 ...

  4. 向docker镜像中传递变量的两种方式

    测试用到的python文件: #!/usr/bin/env python3 #conding: utf-8 from http.server import HTTPServer, BaseHTTPRe ...

  5. 清北学堂 2020 国庆J2考前综合强化 Day4

    目录 1. 题目 T1 写字符串 题目描述 Sol T2 神奇的数 题目描述 Sol T3 珠子染色 题目描述 Sol T4 病毒扩散 题目描述 Sol 算法 -- 图论 1. 题目 T1 写字符串 ...

  6. PHP几个数组函数

    array_intersect比较两个数组的键值,并返回交集: <?php $a1=array("a"=>"red","b"=& ...

  7. Reactive UI -- 反应式编程UI框架入门学习(二)

    前文Reactive UI -- 反应式编程UI框架入门学习(一)  介绍了反应式编程的概念和跨平台ReactiveUI框架的简单应用. 本文通过一个简单的小应用更进一步学习ReactiveUI框架的 ...

  8. Apache DolphinScheduler 社区呼唤志愿者

    DolphinScheduler是什么? Apache DolphinScheduler 是一个分布式.易扩展并带有强大的可视化界面的大数据工作流调度系统. 2021 年 03 月 18 日正式成为 ...

  9. Luogu3435 [POI2006]OKR-Periods of Words (KMP)

    \(next\)应用,将原串视作最长前缀复制后的子串 #include <iostream> #include <cstdio> #include <cstring> ...

  10. Redis 11 配置

    参考源 https://www.bilibili.com/video/BV1S54y1R7SB?spm_id_from=333.999.0.0 版本 本文章基于 Redis 6.2.6 基本配置 Re ...