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. 抓到 Netty 一个 Bug,顺带来透彻地聊一下 Netty 是如何高效接收网络连接的

    本系列Netty源码解析文章基于 4.1.56.Final版本 对于一个高性能网络通讯框架来说,最最重要也是最核心的工作就是如何高效的接收客户端连接,这就好比我们开了一个饭店,那么迎接客人就是饭店最重 ...

  2. 集合-list常用方法总结

    每个方法使用见下方代码详解 点击查看代码 ArrayList list = new ArrayList(); list.add("AA"); list.add(123); list ...

  3. CD 从抓轨到搭建流媒体服务器 —— 以《月临寐乡》为例

    2022-07-19 v0.0.1 由于某些原因,进了 Static World 的群并入坑了 月临寐乡 ,梦开始了.作为幻想乡的新人,也算是有了自己喜欢的社团.但是更细节的东西,狐狐脑子一下子塞不下 ...

  4. 算法竞赛进阶指南0x51 线性DP

    AcWing271. 杨老师的照相排列 思路 这是一个计数的题目,如果乱考虑,肯定会毫无头绪,所以我们从1号到最后一个依次进行安排. 经过反复实验,发现两个规律 每一行的同学必须是从左向右依次连续放置 ...

  5. 缓冲流的原理和BufferedOutputStream字节缓冲输出流

    缓冲流的原理 BufferedOutputStream字节缓冲输出流 package com.yang.Test.BufferedStudy; import java.io.BufferedOutpu ...

  6. flex这些问题应该被理解

    flex三连问,帮助我们更好的理解布局利器 问题: flex的值 auto, none, 0, 1, initial分别是什么?有什么作用?有什么表现? flex-basis和width的区别?单值f ...

  7. 5.1SpringBoot整合Kafka(工具安装Kafka+Tools)

    1.工具安装Kafka 上一期我分享了安装zk,下一次我们把Kafka和可视化工具一起搞起来. 注意:这个时候ZK一定要启动成功. zk安装地址:https://www.cnblogs.com/dao ...

  8. 关于javascript中this

    ------------恢复内容开始------------ 1 var number = 5; 2 var obj = { 3 number: 3, 4 fn1: (function () { 5 ...

  9. Docker Compose安装部署Jenkins

    流水线可以让项目发布流程更加清晰,docker可以大大减少Jenkins配置. 1.前言 数据卷挂载到 /var 磁盘目录下,因为该磁盘空间较大,后面需要挂载容器数据卷,以防内存吃紧. 为了可以留存启 ...

  10. 基于.NetCore开发博客项目 StarBlog - (17) 自动下载文章里的外部图片

    系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetC ...