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. <数据结构系列1>封装自己的数组——手写动态泛型数组(简化版ArrayList)

    哈哈,距离上一次写博客已经快过去半个月了,这这这,好像有点慢啊,话不多说,开始我们的手写动态泛型数组 首先是我们自己写一个自己的动态数组类,代码如下所示: public class Array< ...

  2. Netty源码分析第5章(ByteBuf)---->第6节: 命中缓存的分配

    Netty源码分析第6章: ByteBuf 第六节: 命中缓存的分配 上一小节简单分析了directArena内存分配大概流程, 知道其先命中缓存, 如果命中不到, 则区分配一款连续内存, 这一小节带 ...

  3. 初学node.js-nodejs中实现HTTP服务(3)

    一.node.js实现服务端 创建hello-world-server.js文件,服务端源码如下: /** * node.js实现http服务端 */ var http = require('http ...

  4. 入门向:南邮CTF_ReadAsm2_WP

    题目链接:http://ctf.nuptzj.cn/challenges#ReadAsm2 我比较菜,所以把思路全部敲上来了. 题目很明确告诉我们,这道题考察阅读汇编代码的能力. 在对编译环境和调用约 ...

  5. (转)Django 数据库

         转:https://blog.csdn.net/ayhan_huang/article/details/77575186      目录 数据库说明 配置数据库 在屏幕输出orm操作对应的s ...

  6. Notes of Daily Scrum Meeting(11.8)

    Notes of Daily Scrum Meeting(11.8) 预备中开始写代码的第一天,因为大家对Android编程的熟悉程度还是不够,所以工程进行的非常缓慢,有四名队员 开始编写自己的任务, ...

  7. Daily Scrum 1 --团队项目所需时间估计以及任务分配

    考虑到所有的任务不可能逐一细化分配给成员,我们将需要完成的任务进行了大致的分配.任务所需要的具体实现可以参看<学霸网站NABC> 所需要的总时间一共为44h. 我们会在以后的每日任务中进行 ...

  8. Scrum Meeting 13 -2014.11.19

    最近数据库和编译的实验课也开始了,大家晚上的时间直接被砍掉了大部分. 希望大家能顺利完成项目吧.剩下时间也不多了,如果程序还存在一些特别的问题和需要优化修改的地方也应该考虑留到下阶段进行了. Memb ...

  9. crontab任务不生效

    新建php脚本ctTest.php,代码如下: <?php /****************************************************************** ...

  10. beat冲刺(6/7)

    目录 摘要 团队部分 个人部分 摘要 队名:小白吃 组长博客:hjj 作业博客:beta冲刺(6/7) 团队部分 后敬甲(组长) 过去两天完成了哪些任务 ppt制作 视频拍摄 接下来的计划 准备答辩 ...