Description

今天的数学课上,Crash小朋友学习了最小公倍数(Least Common Multiple)。对于两个正整数a和b,LCM(a, b)表示能同时被a和b整除的最小正整数。例如,LCM(6, 8) = 24。回到家后,Crash还在想着课上学的东西,为了研究最小公倍数,他画了一张N*M的表格。每个格子里写了一个数字,其中第i行第j列的那个格子里写着数为LCM(i, j)。一个4*5的表格如下: 1 2 3 4 5 2 2 6 4 10 3 6 3 12 15 4 4 12 4 20 看着这个表格,Crash想到了很多可以思考的问题。不过他最想解决的问题却是一个十分简单的问题:这个表格中所有数的和是多少。当N和M很大时,Crash就束手无策了,因此他找到了聪明的你用程序帮他解决这个问题。由于最终结果可能会很大,Crash只想知道表格里所有数的和mod 20101009的值。

Input

输入的第一行包含两个正整数,分别表示N和M。

Output

输出一个正整数,表示表格中所有数的和mod 20101009的值。

Sample Input

4 5

Sample Output

122

HINT

100%的数据满足N, M ≤ 10^7。

Solution

莫比乌斯反演,膜拜PoPoQQQ

这题题意还是很清楚的,话不多说,推式子吧

哦,我之前\(too\ young\ too\ simple\)了,分块的时候判上界每次都会取min,结果慢了很多,这次保证了N比M小,所以在推式子的时候不要疑惑

\[ans=\sum_{i=1}^N\sum_{j=1}^Mlcm(i,j)\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \
\]

\[=\sum_{i=1}^N\sum_{j=1}^M\frac{ij}{gcd(i,j)}\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \
\]

\[=\sum_{d=1}^Nd\sum_{i=1}^{\lfloor \frac{N}{d} \rfloor}\sum_{j=1}^{\lfloor \frac{M}{d} \rfloor}[gcd(i,j)=1]ij\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \
\]

这里解释一下,为什么枚举公约数,后面还要是一个\([gcd(i,j)=1]\):因为当\(i\),\(j\)除了\(d\)以外还有公因子\(k\)的话,那么\(gcd(i,j)=dk\),而不是\(d\),这个式子就错了

然后我们设\(g(x,y)=\sum_{i=1}^{x}\sum_{j=1}^{y}[gcd(i,j)=1]ij\),\(s(x,y)=\sum_{i=1}^{x}\sum_{j=1}^{y}ij=\frac{(x+1)x}{2}\frac{(y+1)y}{2}\)

那么

\[ans=\sum_{d=1}^Nd\cdot g(\lfloor \frac{N}{d} \rfloor,\lfloor \frac{M}{d} \rfloor)
\]

假设我们知道\(g(x,y)\)的值,那么算这个式子,整除分块就可以了吧

那么我们接下来的问题就是算\(g(x,y)\)

对于\(g(x,y)\),这里的求法完全是单独的,用莫比乌斯反演。

设\(f(n)=\sum_{i=1}^{x}\sum_{j=1}^{y}[gcd(i,j)=n]ij\)

设\(F(n)=\sum_{i=1}^{x}\sum_{j=1}^{y}[n|gcd(i,j)]ij\)

然后我们来推\(F(n)\)

\(F(n)=\sum_{i=1}^{x}\sum_{j=1}^{y}[n|gcd(i,j)]ij\)

\(\ \ \ \ \ \ \ \ \ \ =\sum_{ni=1}^{x}\sum_{nj=1}^{y}[n|gcd(ni,nj)]ni\cdot nj\)

\(\ \ \ \ \ \ \ \ \ \ =\sum_{i=1}^{\lfloor \frac{x}{n} \rfloor}\sum_{j=1}^{\lfloor \frac{y}{n} \rfloor}ni \cdot nj\)

\(\ \ \ \ \ \ \ \ \ \ =n^2\sum_{i=1}^{\lfloor \frac{x}{n} \rfloor}\sum_{j=1}^{\lfloor \frac{y}{n} \rfloor}ij\)

\(\ \ \ \ \ \ \ \ \ \ =n^2\cdot s(\lfloor \frac{x}{n} \rfloor,\lfloor \frac{y}{n} \rfloor)\)

反演得\(f(n)\)

\(f(n)=\sum_{n|d}\mu(\frac{d}{n})F(d)\)

\(\ \ \ \ \ \ \ \ \ =\sum_{d=1}^{N}\mu(d)F(nd)\)

\(\ \ \ \ \ \ \ \ \ =\sum_{d=1}^{N}\mu(d)\cdot n^2d^2\cdot s(\lfloor \frac{x}{nd} \rfloor,\lfloor \frac{y}{nd} \rfloor)\)

那么\(g(x,y)=f(1)=\sum_{d=1}^{N}\mu(d)\cdot d^2\cdot s(\lfloor \frac{x}{d} \rfloor,\lfloor \frac{y}{d} \rfloor)\)

于是,又可以整除分块了。。。

预处理\(\mu(d)\cdot d^2\)前缀和,分块求\(g(x,y)\)

所以这个题目的算法就是一个大整除分块加一个小整除分块,最后复杂度两个根号乘起来正好一个\(O(N)\)

#include<bits/stdc++.h>
#define ll long long
const int MAXN=10000000+10,Mod=20101009;
int N,M,prime[MAXN],cnt,mu[MAXN],vis[MAXN];
ll res,two,mus[MAXN];
template<typename T> inline void read(T &x)
{
T data=0,w=1;
char ch=0;
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')w=-1,ch=getchar();
while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();
x=data*w;
}
template<typename T> inline void write(T x,char c='\0')
{
if(x<0)putchar('-'),x=-x;
if(x>9)write(x/10);
putchar(x%10+'0');
if(c!='\0')putchar(c);
}
template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
template<typename T> inline T min(T x,T y){return x<y?x:y;}
template<typename T> inline T max(T x,T y){return x>y?x:y;}
inline ll qexp(ll a,ll b)
{
ll res=1;
while(b)
{
if(b&1)res=res*a%Mod;
a=a*a%Mod;
b>>=1;
}
return res;
}
inline void init()
{
two=qexp(2,Mod-2);
memset(vis,1,sizeof(vis));
vis[0]=vis[1]=0;
mu[1]=1;
for(register int i=2;i<MAXN;++i)
{
if(vis[i])
{
prime[++cnt]=i;
mu[i]=-1;
}
for(register int j=1;j<=cnt&&i*prime[j]<MAXN;++j)
{
vis[i*prime[j]]=0;
if(i%prime[j])mu[i*prime[j]]=-mu[i];
else break;
}
}
for(register int i=1;i<MAXN;++i)mus[i]=(mus[i-1]+(ll)mu[i]*(ll)i*(ll)i)%Mod;
}
inline ll s(int x,int y)
{
return (ll)(x+1)*(ll)x%Mod*two%Mod*(ll)(y+1)%Mod*(ll)y%Mod*two%Mod;
}
inline ll g(int x,int y)
{
ll ans=0;
if(x>y)std::swap(x,y);
for(register int i=1;;)
{
if(i>x)break;
int j=min(x/(x/i),y/(y/i));
(ans+=(mus[j]-mus[i-1]+Mod)%Mod*s(x/i,y/i)%Mod)%=Mod;
i=j+1;
}
return ans;
}
int main()
{
read(N);read(M);
init();
if(N>M)std::swap(N,M);
for(register int i=1;;)
{
if(i>N)break;
int j=min(N/(N/i),M/(M/i));
(res+=(ll)(i+j)*(ll)(j-i+1)%Mod*two%Mod*g(N/i,M/i)%Mod)%=Mod;
i=j+1;
}
write(res,'\n');
return 0;
}

【刷题】BZOJ 2154 Crash的数字表格的更多相关文章

  1. 【莫比乌斯反演】关于Mobius反演与lcm的一些关系与问题简化(BZOJ 2154 crash的数字表格&&BZOJ 2693 jzptab)

    BZOJ 2154 crash的数字表格 Description 今天的数学课上,Crash小朋友学习了最小公倍数(Least Common Multiple).对于两个正整数a和b,LCM(a, b ...

  2. [BZOJ 2154]Crash的数字表格(莫比乌斯反演+数论分块)

    [BZOJ 2154]Crash的数字表格(莫比乌斯反演+数论分块) 题面 求 \[\sum_{i=1}^{n} \sum_{j=1}^{m} \mathrm{lcm}(i,j)\] 分析 \[\su ...

  3. [bzoj 2693] jzptab & [bzoj 2154] Crash的数字表格 (莫比乌斯反演)

    题目描述 TTT组数据,给出NNN,MMM,求∑x=1N∑y=1Mlim(x,y)\sum_{x=1}^N\sum_{y=1}^M lim(x,y)\newlinex=1∑N​y=1∑M​lim(x, ...

  4. BZOJ 2154: Crash的数字表格 [莫比乌斯反演]

    2154: Crash的数字表格 Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 2924  Solved: 1091[Submit][Status][ ...

  5. Bzoj 2154: Crash的数字表格(积性函数)

    2154: Crash的数字表格 Time Limit: 20 Sec Memory Limit: 259 MB Description 今天的数学课上,Crash小朋友学习了最小公倍数(Least ...

  6. bzoj 2154 Crash的数字表格(莫比乌斯反演及优化)

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

  7. ●BZOJ 2154 Crash的数字表格

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=2154 题解: 莫比乌斯反演. 题意还是很清楚的,就不赘述了. 显然有 $ANS=\sum_{ ...

  8. BZOJ 2154 Crash的数字表格

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2154 题意: 思路: i64 mou[N]; void init(int N){    ...

  9. BZOJ 2154 Crash的数字表格 ——莫比乌斯反演

    求$\sum_{i=1}^n\sum_{j=1}^n lcm(i,j)$ 枚举因数 $ans=\sum_{d<=n} F(d) * d$ $F(d)$表示给定范围内两两$\sum_{gcd(i, ...

随机推荐

  1. mongodb主从以及auth主从 配置详解

    1.主服务器配置   #auth = true   dbpath = /data/mongodb/db logpath = /data/mongodb/log/mongodb.log   port = ...

  2. UnityEditor扩展-Shader浏览器

    1. 用途 用于浏览项目所有Shader被使用的情况 2. 界面说明 Ignore Directory:添加不搜索的文件夹,不添加默认搜索全部 Find按钮:开始搜索 Used Shaders:已被使 ...

  3. 2.2 Oracle之DML的SQL语句之多表查询以及组函数

    一.SQL的多表查询: 1.左连接和右连接(不重要一方加(+)) SELECT e.empno,e.ename,d.deptno,d.dname,d.loc FROM emp e,dept d WHE ...

  4. Harbor 学习分享系列2 - Harbor项目介绍

    云盘链接 链接:https://pan.baidu.com/s/19yZCZMijf1c3rTwYOqiZzw 密码:netv 通过本文无法把本文中的实验进行成功,请联系作者本人,作者会录制视频发送给 ...

  5. Dede织梦验证码不显示,织梦后台登陆验证码不显示解决方法

    关于"织梦验证码不显示"的解决方法 "织梦验证码无法显示出来"的问题分析? 1.之前显示正常,但是换了服务器后就不能够正常显示:(这种通常是网站程序经过迁移后所 ...

  6. 高可用OpenStack(Queen版)集群-2.基础服务

    参考文档: Install-guide:https://docs.openstack.org/install-guide/ OpenStack High Availability Guide:http ...

  7. Sprint11

    进展:基本设置和显示已经完成,然后是可以通过长按事件弹出对话框可以进行停用.修改.取消该事件提醒的实现,通过触发动作跳转到各个部分页面.

  8. spring冲刺第五天

    昨天进行了地图的初步编写,上网查找了错误的原因,改进了源代码,使程序可以执行. 今天继续编写地图代码,完善地图界面,使其变得美观. 遇到的问题:地图的完善比较难.

  9. caffe可视化模型

    进入$CAFFE_ROOT/python: $ python draw_net.py ../models/bvlc_reference_caffenet/train_val.prototxt caff ...

  10. 【CSAPP笔记】12. 高速缓存存储器

    高速缓存存储器 在存储层次结构中,高速缓存存储器,也叫 cache 是最接近 CPU 寄存器的那一块. 更一般而言,缓存(caching)是一个无所不在的技术.缓存的意思是:对于每层的存储设备,位于 ...