51nod1222 最小公倍数计数 莫比乌斯反演 数学
求$\sum_{i = 1}^{n} \sum_{j = 1}^{i} [lcm(i, j) \le n]$
因为这样不好求,我们改成求$\sum_{i = 1}^{n} \sum_{j = 1}^{n} [lcm(i, j) \le n]$.
这样求出来的值把除了(i, i)这样的点对以外所有点对都重复统计了一次。因此$ans = \frac{rnt + n}{2}$(先加上没有重复统计的点对个数,使得所有点对都重复统计了一次,然后再除2就是不重复统计的点对个数)
接下来就是化式子了...
$$\sum_{i = 1}^{n} \sum_{j = 1}^{n} [lcm(i, j) \le n]$$
$$\sum_{i = 1}^{n} \sum_{j = 1}^{n} [\frac{ij}{(i, j)} \le n]$$
枚举$(i, j) = d$
$$\sum_{d = 1}^{n} \sum_{i = 1}^{n} \sum_{j = 1}^{n} [\frac{ij}{(i, j)} \le n] [(i, j) == d]$$
枚举$i = \frac{i}{d}$
$$\sum_{d = 1}^{n} \sum_{i = 1}^{\lfloor{ \frac{n}{d} }\rfloor} \sum_{j = 1}^{\lfloor{ \frac{n}{d} }\rfloor} [ijd \le n][(i, j) == 1]$$
上反演
$$\sum_{d = 1}^{n} \sum_{i = 1}^{\lfloor{ \frac{n}{d} }\rfloor} \sum_{j = 1}^{\lfloor{ \frac{n}{d} }\rfloor}[ijd \le n] \sum_{k | (i, j)} \mu(k)$$
$$\sum_{d = 1}^{n} \sum_{i = 1}^{\lfloor{ \frac{n}{d} }\rfloor} \sum_{j = 1}^{\lfloor{ \frac{n}{d} }\rfloor} \sum_{k | (i, j)} \mu(k)[ijd \le n]$$
把$k$提到前面来,然后枚举$k$的倍数
$$\sum_{d = 1}^{n} \sum_{k = 1}^{\lfloor{ \frac{n}{d} }\rfloor} \mu(k) \sum_{i = 1 }^{\lfloor{ \frac{n}{dk} }\rfloor} \sum_{j = 1}^{\lfloor{ \frac{n}{dk} }\rfloor}[i j k^2 d \le n]$$
可以发现,原式中对$d,k$的限制实际上是$dk \le n$,因此我们再次将$k$向前提,那么此时$k$已经是第一个枚举的了,因此我们对中括号内的式子进行移项得到:
$$\sum_{k = 1}^{n} \mu(k) \sum_{d = 1}^{\lfloor{ \frac{n}{k} }\rfloor} \sum_{i = 1}^{\lfloor{ \frac{n}{dk} }\rfloor} \sum_{j = 1}^{\lfloor{ \frac{n}{dk} }\rfloor}[ijd \le \frac{n}{k^2}]$$
那么为了保证$[ijd \le \frac{n}{k^2}]$,对现在枚举的变量有如下限制:
$k \le \sqrt{n}, d \le \lfloor{ \frac{n}{k^2} }\rfloor, x \le \lfloor{ \frac{n}{k^2d} }\rfloor, y \le \lfloor{ \frac{n}{k^2dx} }\rfloor$
因此原式变为:
$$\sum_{k = 1}^{\sqrt{n}} \mu(k) \sum_{d = 1}^{\lfloor{ \frac{n}{k^2} }\rfloor} \sum_{i = 1}^{\lfloor{ \frac{n}{k^2d} }\rfloor} \sum_{j = 1}^{\lfloor{ \frac{n}{k^2dx} }\rfloor} 1$$
设$H(n) = \sum_{a = 1}^{n} \sum_{b = 1}^{\lfloor{ \frac{n}{a} }\rfloor} \sum_{c = 1}^{\lfloor{ \frac{n}{ab} }\rfloor} 1$,则原式为:
$$\sum_{k = 1}^{\sqrt{n}} \mu(k) H(\lfloor{ \frac{n}{k^2} }\rfloor)$$
因此我们的目的就是快速求出$H(n)$。
$H(n)$可以看做是求满足如下关系的三元组的个数$abc \le n$.
因此我们不妨假设$a < b < c$,那么有$a \le n ^ {\frac{1}{3}}, b \le \sqrt{\lfloor{ \frac{n}{a} }\rfloor}$(因为除去$a$后剩余数为$\lfloor{ \frac{n}{a} }\rfloor$,而$b$最大也要满足$b \le c$,因此$b$最大也就是开根)
那么此时$c$的范围就为$[b + 1, \lfloor \frac{n}{ab} \rfloor]$,因此$c$的个数可以$O(1)$算出
因为我们假定了$a < b < c$,而原式中没有这样的限制,所以这样会少算,比如$123$会被计算一次,但实际上应该被计算$123, 132, 213, 231, 321, 312$共$6$次。其他情况也是类似的。
因此我们枚举$a, b, c$,分别求3个均不相同,前2个相同,后2个相同,3个都相同的方案数,
然后对于这些方案数,分别乘上对应系数$6, 3, 3, 1$.最后加起来就等于$H(n)$.
#include<bits/stdc++.h>
using namespace std;
#define AC 401000
#define LL long long
#define R register int
#define RL register LL LL l, r, tot, maxn;
LL pri[AC], mu[AC];
bool z[AC]; void pre()
{
scanf("%lld%lld", &l, &r), maxn = sqrt(r);
mu[] = ;
for(R i = ; i <= maxn; i ++)
{
if(!z[i]) pri[++ tot] = i, mu[i] = -;
for(R j = ; j <= tot; j ++)
{
int now = pri[j];
if(i * now > maxn) break;
z[i * now] = true;
if(!(i % now)) break;
mu[i * now] = - mu[i];
}
}
} LL get(LL n)
{
LL A = , B = , C = , D = ;
for(RL i = ; i * i * i <= n; i ++)//枚举3个不相同的
{
LL m2 = sqrt(n / i), to = n / i;//因为k要从j + 1 枚举到 n / i / j,所以相减就是个数
for(RL j = i + ; j <= m2; j ++) A += (LL)(to / j - j);//除法如此之慢。。。。
}
for(RL i = ; i * i * i <= n; i ++) B += (LL)(n / i / i - i);//加上只有前2个相同的
for(RL i = ; i * i * i <= n; i ++) C += ((LL)sqrt(n / i) - i);//枚举后2个相同的,因为后2个相同,所以只需要知道j的个数即可
for(RL i = ; i * i * i <= n; i ++) ++ D;//因为诡异精度误差,,,,就算是加减,也要先转成LL....
// D += m1;//因为前面是double类型,所以一遇到乘法,就可能造成进位。。。
return A * + B * + C * + D;
} LL cal(LL n)
{
int block = sqrt(n); LL rnt = ;
for(R i = ; i <= block; i ++) rnt += mu[i] * get(n / i / i);
return (rnt + n) / ;
} int main()
{
freopen("in.in", "r", stdin);
pre();
printf("%lld\n", cal(r) - cal(l - ));
fclose(stdin);
return ;
}
51nod1222 最小公倍数计数 莫比乌斯反演 数学的更多相关文章
- 【51nod】1222 最小公倍数计数 莫比乌斯反演+组合计数
[题意]给定a和b,求满足a<=lcm(x,y)<=b && x<y的数对(x,y)个数.a,b<=10^11. [算法]莫比乌斯反演+组合计数 [题解]★具体 ...
- 51NOD 1222 最小公倍数计数 [莫比乌斯反演 杜教筛]
1222 最小公倍数计数 题意:求有多少数对\((a,b):a<b\)满足\(lcm(a,b) \in [1, n]\) \(n \le 10^{11}\) 卡内存! 枚举\(gcd, \fra ...
- 51nod1222 最小公倍数计数
题目来源: Project Euler 基准时间限制:6 秒 空间限制:131072 KB 分值: 640 定义F(n)表示最小公倍数为n的二元组的数量. 即:如果存在两个数(二元组)X,Y(X & ...
- UOJ #54 时空穿梭 —— 计数+莫比乌斯反演+多项式系数
题目:http://uoj.ac/problem/54 10分还要用 Lucas 定理囧...因为模数太小了不能直接算... #include<cstdio> #include<cs ...
- luogu 4844 LJJ爱数数 (莫比乌斯反演+数学推导)
题目大意:求满足gcd(a,b,c)==1,1/a+1/b=1/c,a,b,c<=n的{a,b,c}有序三元组个数 因为题目里有LJJ我才做的这道题 出题人官方题解https://www.cnb ...
- [51nod1222] 最小公倍数计数(莫比乌斯反演)
题面 传送门 题解 我此生可能注定要和反演过不去了--死都看不出来为啥它会突然繁衍反演起来啊-- 设\(f(n)=\sum_{i=1}^n\sum_{j=1}^n[{ij\over\gcd(i,j)} ...
- 51Nod1222 最小公倍数计数 数论 Min_25 筛
原文链接https://www.cnblogs.com/zhouzhendong/p/51Nod1222.html 题意 给定 $a,b$, 求 $$\sum_{n=a}^b \sum_{i=1}^n ...
- 51nod1222最小公倍数计数
51nod1222 http://210.33.19.103/contest/1113/problem/2 同学的神仙做法: 首先考虑先去掉X<=Y的限制,也就是先计算满足要求的任意有序pair ...
- BZOJ 3518 点组计数 ——莫比乌斯反演
要求$ans=\sum_{i=1}^n \sum_{j=1}^m (n-i)(m-j)(gcd(i,j)-1)$ 可以看做枚举矩阵的大小,然后左下右上必须取的方案数. 这是斜率单增的情况 然后大力反演 ...
随机推荐
- jenkins统计单元测试的覆盖率
前提:单元测试和被测代码在一个仓库 maven的pom配置 依赖增加 <dependency> <groupId>org.jacoco</groupId> < ...
- 开源工具 | 手游自动化框架GAutomator,新增iOS系统和UE4引擎支
WeTest 导读 GAutomator是腾讯WeTest推出的手游自动化测试框架,已用于腾讯多个手游项目组的自动化测试. 1.GAutomator诞生背后 研究过手游自动化测试的同学都知道,虽然市场 ...
- SQL创建数据库、建表、填入内容
--创建数据库 create database Information go --使用数据库 use Information go --创建表 create table Student ( Sno ) ...
- Linux学习(一)------CentOs安装mysql5.5 数据库
具体方法和步骤如下所示: 1.第一步就是看linu是否安装了mysql,经过rpm -qa|grep mysql查看到centos下安装了mysql5.1,那就开始卸载咯 2.接下来就是卸载mysql ...
- google::protobuf 编译方法
这两天用了一下Protobuf 感觉很方便, 记录一下编译过程, 以做务忘(需要安装cmake): 1: 下载地址: https://developers.google.com/protocol-bu ...
- List Leaves 树的层序遍历
3-树2 List Leaves (25 分) Given a tree, you are supposed to list all the leaves in the order of top do ...
- centos7挂载Windows共享文件夹(学习笔记)
centos7挂载windows共享文件夹 练习环境:centos7是安装在台式机的虚拟机,Windows共享文件夹是公司服务器的共享文件夹(已设置好的共享) 步骤 1. 设置挂载点:mkdir /m ...
- CsvHelper文档-3写
CsvHelper文档-3写 不用做任何设置,默认的情况下,csvhelper就可以很好的工作了.如果你的类的属性名称和csv的header名称匹配,那么可以按照下面的例子写入: var record ...
- xpath抓取的值有\r\n\t时,去掉的方法
解决办法: normalize-space() 例子: 原来的xpath为: user=selector.xpath('//*[@id="Con"]/tr[1]/th/text() ...
- React 初学
React.createClass({}); getInitialState,this.setState({}); {}解读代码块,外层不要加引号,比如onChange={this.handleCha ...