【BZOJ2154】Crash的数字表格(莫比乌斯反演)

题面

BZOJ

简化题意:

给定\(n,m\)

求$$\sum_{i=1}n\sum_{j=1}mlcm(i,j)$$

题解

以下的一切都默认\(n<m\)

我们都知道\(lcm(i,j)=\frac{ij}{gcd(i,j)}\)

所以所求化简

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

看到\(gcd(i,j)\)很不爽,于是就再提出来

\[\sum_{d=1}^{n}\sum_{i=1}^n\sum_{j=1}^m[gcd(i,j)==d]\frac{ij}{d}
\]

也就是

\[\sum_{d=1}^{n}\sum_{i=1}^{n/d}\sum_{j=1}^{m/d}[gcd(i,j)==1]{ijd}
\]

把\(d\)提出来

\[ans=\sum_{d=1}^{n}d\sum_{i=1}^{n/d}\sum_{j=1}^{m/d}[gcd(i,j)==1]{ij}
\]

前面这一堆看起来管不了了

看后面的一段

\[\sum_{i=1}^{n/d}\sum_{j=1}^{m/d}[gcd(i,j)==1]{ij}
\]

看到\(n/d\)这种东西很不爽呀

就写成这样吧。。

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

这种东西怎么求?

令$$f(d)=\sum_{i=1}{x}\sum_{j=1}{y}[gcd(i,j)==d]{ij}$$

根据莫比乌斯反演的常见套路

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

直接把\(d\)提出来

\[G(d)=d^2\sum_{i=1}^{x/d}\sum_{j=1}^{y/d}[1|gcd(i,j)]{ij}
\]

\(1|gcd(i,j)\)是显然成立的

所以$$G(d)=d2\sum_{i=1}{x/d}\sum_{j=1}^{y/d}{ij}$$

这玩意明显可以\(O(1)\)求(相当于两个等差数列相乘)

所以,要求的东西就是$$f(1)=\sum_{i=1}^x\mu(i)G(i)$$

这道题就解决了一大半了

现在我们的复杂度是\(O(n\sqrt n)\)与\(O(n^2)\)之间

需要继续优化

很显然的

\[ans=\sum_{d=1}^{n}d\sum_{i=1}^{n/d}\sum_{j=1}^{m/d}[gcd(i,j)==1]{ij}
\]

这个式子可以数论分块一波,复杂度少了\(O(\sqrt n)\)

还不够

继续看,

\[f(1)=\sum_{i=1}^x\mu(i)G(i)
\]

这个式子把\(G(x)\)展开

\[f(1)=\sum_{i=1}^x\mu(i)i^2\sum_{i=1}^{x/d}\sum_{j=1}^{y/d}{ij}
\]

还是可以数论分块

但是要预处理\(\mu(i)*i^2\)的前缀和

然后复杂度就成了\(O(n)\)啦

注释掉的是没用数论分块的式子

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define MOD 20101009
#define MAX 12000000
#define ll long long
inline int read()
{
int x=0,t=1;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*t;
}
int mu[MAX],pri[MAX],tot;
bool zs[MAX];
int n,m;
int G[MAX],ans;
int smu[MAX],sqr[MAX];
void Getmu()
{
zs[1]=true;mu[1]=1;
for(int i=2;i<=n;++i)
{
if(!zs[i]){pri[++tot]=i;mu[i]=-1;}
for(int j=1;j<=tot&&i*pri[j]<=n;++j)
{
zs[i*pri[j]]=true;
if(i%pri[j])mu[i*pri[j]]=-mu[i];
else{mu[i*pri[j]]=0;break;}
}
}
for(int i=1;i<=n;++i)smu[i]=(smu[i-1]+mu[i]+MOD)%MOD;
}
int Solve(int xx,int yy)
{
long long ans=0;
//for(int i=1;i<=xx;++i)G[i]=1ll*i*i%MOD*1ll*(1ll*(1+xx/i)*(xx/i)/2%MOD)*(1ll*(1+yy/i)*(yy/i)/2%MOD)%MOD;
//for(int i=1;i<=xx;++i)ans=(ans+1ll*mu[i]*G[i]%MOD+MOD)%MOD;
int i=1,j;
while(i<=xx)
{
j=min(xx/(xx/i),yy/(yy/i));
int GG=1ll*(1ll*(1+xx/i)*(xx/i)/2%MOD)*(1ll*(1+yy/i)*(yy/i)/2%MOD)%MOD;
ans+=1ll*(sqr[j]-sqr[i-1])%MOD*GG%MOD;
ans%=MOD;
i=j+1;
}
return (ans+MOD)%MOD;
}
int main()
{
n=read();m=read();
if(n>m)swap(n,m);
Getmu();
for(int i=1;i<=n;++i)sqr[i]=(sqr[i-1]+1ll*i*i%MOD*mu[i]%MOD+MOD)%MOD;
//for(int i=1;i<=n;++i)ans=1ll*((ans+1ll*i*Solve(n/i,m/i))%MOD)%MOD;
int i=1,j;
while(i<=n)
{
j=min(n/(n/i),m/(m/i));
int t=1ll*(i+j)*(j-i+1)/2%MOD;
ans=(ans+1ll*Solve(n/i,m/i)*t%MOD)%MOD;
i=j+1;
}
printf("%d\n",ans);
return 0;
}

【BZOJ2154】Crash的数字表格(莫比乌斯反演)的更多相关文章

  1. bzoj2154: Crash的数字表格 莫比乌斯反演

    题意:求\(\sum_{i=1}^n \sum_{j=1}^m\frac{i*j}{gcd(i,j)}\) 题解:\(ans=\sum_{i=1}^n\sum_{j=1}^m \frac{i*j}{g ...

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

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

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

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

  4. [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, ...

  5. 【bzoj2154】Crash的数字表格 莫比乌斯反演

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

  6. 【BZOJ】2154: Crash的数字表格 莫比乌斯反演

    [题意]给定n,m,求Σlcm(i,j),1<=i<=n,1<=j<=m,n,m<=10^7. [算法]数论(莫比乌斯反演) [题解] $$ans=\sum_{i\leq ...

  7. 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, ...

  8. [国家集训队] Crash的数字表格 - 莫比乌斯反演,整除分块

    考虑到\(lcm(i,j)=\frac{ij}{gcd(i,j)}\) \(\sum_{i=1}^n\sum_{j=1}^m\frac{ij}{gcd(i,j)}\) \(\sum_{d=1}^{n} ...

  9. [bzoj2154]Crash的数字表格(mobius反演)

    题意:$\sum\limits_{i = 1}^n {\sum\limits_{j = 1}^m {lcm(i,j)} } $ 解题关键: $\sum\limits_{i = 1}^n {\sum\l ...

  10. 洛谷 - P1829 - Crash的数字表格 - 莫比乌斯反演

    求: \(S(n,m)=\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}lcm(i,j)\) 显然: \(S(n,m)=\sum\limits_{i=1}^{n}\ ...

随机推荐

  1. LeetCode - 728. Self Dividing Numbers

    A self-dividing number is a number that is divisible by every digit it contains. For example, 128 is ...

  2. Nginx与Tomcat/PHP架构优化的技术分享

    PHP性能优化 一般我们是在/usr/local/php5/etc/php-fpm.conf这个文件里面进行相应的配置. 1)       如果设置成static,php-fpm进程数自始至终都是pm ...

  3. hiveql函数笔记(二)

    1.数据查询 //提高聚合的性能 SET hive.map.aggr=true; SELECT count(*),avg(salary) FROM employees; //木匾不允许在一个查询语句中 ...

  4. ps通道抠章

    1. 打开图片 2. 使用椭圆形选框工具,选择章所在范围(ALT+SHITF+鼠标左键) 3.复制图层(CTRL+J)为图层1,隐藏背景 4.进入通道,选择对比度最大的通道,复制通道副本 5.反选(C ...

  5. C++11 左值、右值、右值引用详解

    C++11 左值.右值.右值引用详解 左值.右值 在C++11中所有的值必属于左值.右值两者之一,右值又可以细分为纯右值.将亡值. 在C++11中可以取地址的.有名字的就是左值,反之,不能取地址的.没 ...

  6. Angular4.0用命令行创建组件服务出错

    之前使用cnpm创建的angular4.0项目,由于cnpm下载的node_modules资源经常会有部分缺失,所以在用命令行创建模板.服务的时候会报错: Error: ELOOP: too many ...

  7. hdu1995 汉诺塔V

    可以直接把前K-1个罗盘全部忽略了,因为移动前K-1个罗盘不会影响第K个. 也就是相当于只移动剩下的n-k-1个罗盘,当只移动第k个罗盘时,f(k)=1;当要哟东第k个和第k+1个时,就必须先把第k个 ...

  8. jsp去除空行的web.xml配置

    在jsp中我们引入的标签,例如jstl的标签,循环遍历等等,可能会产生很多空行,其实也没什么,不会影响展示,但是空行多多少少会影响性能,这是我们只需要在web.xml中配置一下我们就可以很简单的去掉, ...

  9. org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.coder520.mamabike.user.dao.UserMapper.selectByPrimaryKey

    这个异常是IDEA中漏加载mapper.xml文件,在classes中没找到,所以要在配置文件中加入: !--如果不添加此节点mybatis的mapper.xml文件都会被漏掉.--> < ...

  10. C语言拼接字符串以及进制转换

    #include<stdio.h> #include<stdlib.h> #include<string.h> char *join1(char *, char*) ...