P1829 [国家集训队]Crash的数字表格
P1829 [国家集训队]Crash的数字表格
前置芝士
莫比乌斯反演
乘法逆元
数论分块
正文
//补充:以下式子中的除法均为整除
由题目可以得知,这道题让我们所求的数,用一个式子来表达即为:\(\boxed{ANS=\sum_{i=1}^n \sum_{j=1}^m LCM(i,j)}\)
而根据莫比乌斯反演的内容,我们可以对右边的式子进行进一步的推导:
\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}\) ,则有以下推论:
\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)}\),则有:
g(K)&=\sum_{d|K} K d \mu (d)\\
&=K \sum_{d|K} \mu(d) d\\
&=K f(K)\\
\end{align}
\]
这里我们定义了一个函数:\(f\),其性质为:
\]
我们可以立马发现函数 \(f\) 是一个积性函数,若我们设 \(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\) 的预处理,接下来便是计算答案了。不过,先别着急,我们再来看一看推导后的式子:
\]
是不是发现了一个惊喜?相信读者在学习完数论分块的内容后会很容易地发现:这个式子是可以通过数论分块进行进一步优化的。接下来,我们将对这一步的优化进行解释:
既然我们定义了函数 \(g\) ,我们先把 \(g\) 带进上面的式子。
\]
接着,因为我们已经预处理完了函数 \(f\) ,那么便可以用 \(f\) 来表示 \(g\) 。
\]
现在已经很明显了:我们可以对这个\(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的数字表格的更多相关文章
- [Luogu P1829] [国家集训队]Crash的数字表格 / JZPTAB (莫比乌斯反演)
题面 传送门:洛咕 Solution 调到自闭,我好菜啊 为了方便讨论,以下式子\(m>=n\) 为了方便书写,以下式子中的除号均为向下取整 我们来颓柿子吧qwq 显然,题目让我们求: \(\l ...
- 洛谷 P1829 [国家集训队]Crash的数字表格 / JZPTAB 解题报告
[国家集训队]Crash的数字表格 / JZPTAB 题意 求\(\sum\limits_{i=1}^n\sum\limits_{j=1}^mlcm(i,j)\),\(n,m\le 10^7\) 鉴于 ...
- 洛谷P1829 [国家集训队]Crash的数字表格 / JZPTAB(莫比乌斯反演)
题目背景 提示:原 P1829 半数集问题 已经迁移至 P1028 数的计算 题目描述 今天的数学课上,Crash小朋友学习了最小公倍数(Least Common Multiple).对于两个正整数a ...
- 洛谷P1829 [国家集训队]Crash的数字表格
题目描述 今天的数学课上,Crash小朋友学习了最小公倍数(Least Common Multiple).对于两个正整数a和b,LCM(a, b)表示能同时整除a和b的最小正整数.例如,LCM(6, ...
- P1829 [国家集训队]Crash的数字表格 / JZPTAB
推式子太快乐啦!虽然我好蠢而且dummy和maomao好巨(划掉) 思路 莫比乌斯反演的题目 首先这题有\(O(\sqrt n)\)的做法但是我没写咕咕咕 然后就是爆推一波式子 \[ \sum_{i= ...
- 洛谷P1829 [国家集训队]Crash的数字表格 / JZPTAB(莫比乌斯反演)
传送门 式子好麻烦orz……大佬好腻害orz->这里 //minamoto #include<iostream> #include<cstdio> #define ll ...
- 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 ...
- 洛谷 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 ...
- 题解-[国家集训队]Crash的数字表格 / JZPTAB
题解-[国家集训队]Crash的数字表格 / JZPTAB 前置知识: 莫比乌斯反演 </> [国家集训队]Crash的数字表格 / JZPTAB 单组测试数据,给定 \(n,m\) ,求 ...
随机推荐
- 最小生成树 链式前向星 Prim&Kruskal
Prim: Prim的思想是将任意节点作为根,再找出与之相邻的所有边(用一遍循环即可),再将新节点更新并以此节点作为根继续搜,维护一个数组:dis,作用为已用点到未用点的最短距离. 证明:Prim算法 ...
- Linux操作系统(4):磁盘分区、挂载
Outline: ① lsblk :查看所有设备挂载情况 ② df -h :查询系统整体磁盘使用情况 ③ du -h /目录 :查询指定目录的磁盘占用情况 ④ mount :查询系统中已经挂载的设备 ...
- squareline搭档OneOS图形组件之可视化GUI开发
LVGL+OneOS! LVGL,一款很火的GUI开发库,一个高度可裁剪.低资源占用.界面美观且易用的嵌入式系统图形库.本身并不依赖特定的硬件平台,任何满足LVGL硬件配置要求的微控制器均可运行LVG ...
- C语言-直接排序
#include<stdio.h> #define MAXSIZE 100 typedef int KeyType; typedef struct { KeyType key; }Reco ...
- java。多态
package Demo.oop.APP.Demo05; public class application { public static void main(String[] args) { //一 ...
- antd vue 折叠面板 v-for 循环点击无效
问题描述 实现一个折叠面板点击展开,但是必须点击两次才能展开,第一次无效 <a-collapse-panel v-for="(item, index) in dataMap" ...
- npm相关资料
npm 源的配置 命令行模式 npm install XXX --registry https://registry.npmmirror.com/ 项目模式 在项目更目录新建.npmrc 文件,内容 ...
- 5-6 Elasticsearch
Elasticsearch概述 什么是Elasticsearch elastic:富有弹性的 search:搜索 在计算机开发界简称ES 这个软件不是SpringCloud的组件,甚至其他语言都可以使 ...
- 减省 Java 小半内存,Solon v1.9.2 发布
相对于 Spring Boot 和 Spring Cloud 的项目: 启动快 5 - 10 倍. (更快) qps 高 2- 3 倍. (更高) 运行时内存节省 1/3 ~ 1/2. (更少) 打包 ...
- python 操作pdf文档
简介 在实际项目中,我们有可能需要提取当中的部分内容并导出,给PDF文件添加水印,合并多份PDF文件等等,而本文会着重用到PyPDF2模块来玩转PDF文档,以及tabula模块来对PDF文档中的表格数 ...