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. html元素height(width)是怎么确定的?

    1.若height是确定的(比如height:100px),则height直接可确定(还受min-height,max-height影响,见height,min-height,max-heigth的作 ...

  2. el-form 每行显示两列,底部按钮居中

    需求: el-form 每行显示两列,底部按钮居中 问题: 以前的解决办法是: el-col, el-row.但是这里只有一个 el-form-item 的 label 数据是已知的,其余项都是循环得 ...

  3. linux学习系列--初识Linux系统

    ### 认识Linux- Linux是一种类UNIX的系统,Unix是1965年在贝尔实验室开发的一个项目,用来开发操作系统- Linux之父-Linus Torvalds在1991年10月5日,他在 ...

  4. Graph Theory の brief introduction

    一. 图的概念   1.定义   某类具体事物(顶点)和这些事物之间的联系(边),由顶点(vertex)和边(edge)组成, 顶点的集合V,边的集合E,图记为G = (V,E) 2.分类     1 ...

  5. 0202年,您真的需要Thrift这样一个RPC微服务框架来拯救一下传统HTTP接口(api)了

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_104 目前市面上类似Django的drf框架基于json的http接口解决方案大行其道,人们也热衷于在接口不多.系统与系统交互较少 ...

  6. Odoo env.ref()函数

    python env.ref()函数作用是获取xml id记录. 1 action = self.env.ref('base.res_company_action').read()[0] 2 acti ...

  7. 用JavaScript写随机出一个颜色

    function changeColor(){ var r = parseInt(Math.random()*255) var g = parseInt(Math.random()*255) var ...

  8. Redis 11 配置

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

  9. mongo数据同步的三种方案

    (一)直接复制data目录(需要停止源和目标的mongo服务)1.针对目标mongo服务已经存在,并正在运行的(mongo2-->mongo).执行步骤:(1).停止源/目标服务器的mongo服 ...

  10. fast json 乱序问题解决过程

    解决问题:保存到redis中的jsonstring在转回jsonObject的时候乱序: 解决方案:https://inlhx.iteye.com/blog/2312512 解决过程: 1 看fast ...