题目描述

设d(x)d(x)d(x)为xxx的约数个数,给定NNN、MMM,求 ∑i=1N∑j=1Md(ij)\sum^{N}_{i=1}\sum^{M}_{j=1} d(ij)i=1∑N​j=1∑M​d(ij)

N,M,T&lt;=50000N,M,T&lt;=50000N,M,T<=50000

题目分析

首先很不显然的有这样一个结论:

d(ij)=∑x∣i∑y∣j[(x,y)==1]d(ij)=\sum_{x|i}\sum_{y|j}[(x,y)==1]d(ij)=x∣i∑​y∣j∑​[(x,y)==1]

证明如下

将一个数唯一质因数分解为p1k1p2k2p3k3...pnknp_1^{k_1}p_2^{k_2}p_3^{k_3}...p_n^{k_n}p1k1​​p2k2​​p3k3​​...pnkn​​,其约数个数为(k1+1)(k2+1)(k3+1)...(kn+1)(k_1+1)(k_2+1)(k_3+1)...(k_n+1)(k1​+1)(k2​+1)(k3​+1)...(kn​+1)

考虑一个质数ppp对d(ij)d(ij)d(ij)的影响,假设iii分解质因数后有kkk个ppp,jjj分解质因数后有qqq个ppp,则产生的贡献即为k+q+1k+q+1k+q+1,接下来是关键的一步(反正我想不到XD)

k+q+1=∑x=0k∑y=0q[(px,py)==1]k+q+1=\sum_{x=0}^k\sum_{y=0}^q[(p^x,p^y)==1]k+q+1=x=0∑k​y=0∑q​[(px,py)==1]

(此句可自行忽略:只有当xy=0xy=0xy=0时才会有值,这就相当于一个(k+1)∗(q+1)(k+1)∗(q+1)(k+1)∗(q+1)的矩形,只取了左下角的LLL字型的一块)

根据乘法原理,有

d(ij)=∑x1=0k1∑y1=0q1[(p1x1,p1y1)==1]∗∑x2=0k2∑y2=0q2[(p2x2,p2y2)==1]⋅⋅⋅∗∑xn=0kn∑yn=0qn[(pnxn,pnyn)==1]
d(ij)=\sum_{x_1=0}^{k_1}\sum_{y_1=0}^{q_1}[(p_1^{x_1},p_1^{y_1})==1]\newline
*\sum_{x_2=0}^{k_2}\sum_{y_2=0}^{q_2}[(p_2^{x_2},p_2^{y_2})==1]\newline
···\newline
*\sum_{x_n=0}^{k_n}\sum_{y_n=0}^{q_n}[(p_n^{x_n},p_n^{y_n})==1]
d(ij)=x1​=0∑k1​​y1​=0∑q1​​[(p1x1​​,p1y1​​)==1]∗x2​=0∑k2​​y2​=0∑q2​​[(p2x2​​,p2y2​​)==1]⋅⋅⋅∗xn​=0∑kn​​yn​=0∑qn​​[(pnxn​​,pnyn​​)==1]

因为必须满足所有(pnxn,pnyn)==1(p_n^{x_n},p_n^{y_n})==1(pnxn​​,pnyn​​)==1才会对答案造成贡献,则可以变形为(∏i=1npnxn,∏i=1npnyn)==1(\prod_{i=1}^np_n^{x_n},\prod_{i=1}^np_n^{y_n})==1(i=1∏n​pnxn​​,i=1∏n​pnyn​​)==1

所以d(ij)=∑x∣i∑y∣j[(x,y)==1]d(ij)=\sum_{x|i}\sum_{y|j}[(x,y)==1]d(ij)=x∣i∑​y∣j∑​[(x,y)==1]

(以上证明摘自:传送门)

证毕

现在就有了Ans=∑i=1N∑j=1M∑x∣i∑y∣j[(x,y)==1]Ans=\sum_{i=1}^{N}\sum_{j=1}^{M}\sum_{x|i}^{}\sum_{y|j}^{}[(x,y)==1]Ans=i=1∑N​j=1∑M​x∣i∑​y∣j∑​[(x,y)==1]

根据数论中切换枚举次序的套路以及莫比乌斯反演对布尔条件框的替换,我们得到

Ans=∑x=1N∑y=1M⌊Nx⌋⌊My⌋[(x,y)==1]=∑x=1N∑y=1M⌊Nx⌋⌊My⌋∑k∣(x,y)μ(k)=∑k=1min(N,M)μ(k)∑k∣x⌊Nx⌋∑k∣y⌊My⌋=∑k=1min(N,M)μ(k)∑x=1⌊Nk⌋⌊Nkx⌋∑y=1⌊Mk⌋⌊Mky⌋
Ans=\sum_{x=1}^{N}\sum_{y=1}^{M}⌊\frac{N}{x}⌋⌊\frac{M}{y}⌋[(x,y)==1]\newline
=\sum_{x=1}^{N}\sum_{y=1}^{M}⌊\frac{N}{x}⌋⌊\frac{M}{y}⌋\sum_{k|(x,y)}\mu(k)\newline
=\sum_{k=1}^{min(N,M)}\mu(k)\sum_{k|x}^{}⌊\frac{N}{x}⌋\sum_{k|y}^{}⌊\frac{M}{y}⌋\newline
=\sum_{k=1}^{min(N,M)}\mu(k)\sum_{x=1}^{⌊\frac{N}{k}⌋}⌊\frac{N}{kx}⌋\sum_{y=1}^{⌊\frac{M}{k}⌋}⌊\frac{M}{ky}⌋
Ans=x=1∑N​y=1∑M​⌊xN​⌋⌊yM​⌋[(x,y)==1]=x=1∑N​y=1∑M​⌊xN​⌋⌊yM​⌋k∣(x,y)∑​μ(k)=k=1∑min(N,M)​μ(k)k∣x∑​⌊xN​⌋k∣y∑​⌊yM​⌋=k=1∑min(N,M)​μ(k)x=1∑⌊kN​⌋​⌊kxN​⌋y=1∑⌊kM​⌋​⌊kyM​⌋

于是这里使用分块优化,预处理μ\muμ的前缀和

最后考虑后面的两个Sigma怎么处理

可以观察发现它们都是∑i=1n⌊ni⌋\sum_{i=1}^{n}⌊\frac{n}{i}⌋∑i=1n​⌊in​⌋的形式,此处可以用分块优化Θ(nn)\Theta(n\sqrt{n})Θ(nn​)预处理

其实还可以Θ(n)\Theta(n)Θ(n)预处理,可以发现∑i=1n⌊ni⌋=∑i=1n∑i∣dn1\sum_{i=1}^{n}⌊\frac{n}{i}⌋=\sum_{i=1}^{n}\sum_{i|d}^{n}1∑i=1n​⌊in​⌋=∑i=1n​∑i∣dn​1

显然是约数个数和d(n)d(n)d(n)的前缀和函数,于是线性筛出μ(n)\mu(n)μ(n)与d(n)d(n)d(n),求出前缀和即可

每次询问Θ(n)\Theta(\sqrt{n})Θ(n​), 预处理Θ(n)\Theta(n)Θ(n),总时间复杂度为Θ(nn)\Theta(n\sqrt{n})Θ(nn​)

TIPS

线性筛约数个数时存一下最小的质数p1p_1p1​的次方+1+1+1,即存下(k1+1)(k_1+1)(k1​+1)就可以方便的线性筛了

线性筛约数和同理,存一下最小的质数p1p_1p1​所对应的首项为111,公比为p1p_1p1​,项数为k1+1k_1+1k1​+1的等比数列,即存下∑i=1k1p1i\sum_{i=1}^{k_1}p_1^i∑i=1k1​​p1i​就可以愉快的线性筛了

AC code
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int MAXN = 100001;
namespace Mobius
{
#define LL long long
int Prime[MAXN], Cnt, mu[MAXN], d[MAXN], Minseq[MAXN];
bool IsnotPrime[MAXN];
LL sum_MU[MAXN], sum_D[MAXN];
void init()
{
mu[1] = d[1] = Minseq[1] = 1;
for(int i = 2; i < MAXN; ++i)
{
if(!IsnotPrime[i])
Prime[++Cnt] = i, mu[i] = -1, d[i] = Minseq[i] = 2;
for(int j = 1; j <= Cnt && i * Prime[j] < MAXN; ++j)
{
IsnotPrime[i * Prime[j]] = 1;
if(i % Prime[j] == 0)
{
Minseq[i * Prime[j]] = Minseq[i]+1;
mu[i * Prime[j]] = 0;
d[i * Prime[j]] = d[i] / Minseq[i] * Minseq[i * Prime[j]];
break;
}
Minseq[i * Prime[j]] = 2;
mu[i * Prime[j]] = -mu[i];
d[i * Prime[j]] = d[i]<<1;
}
}
for(int i = 1; i < MAXN; ++i)
sum_MU[i] = sum_MU[i-1] + mu[i],
sum_D[i] = sum_D[i-1] + d[i];
}
LL calc(int N, int M)
{
if(N > M) swap(N, M);
LL ret = 0;
for(int i = 1, j; i <= N; i=j+1)
{
j = min(N/(N/i), M/(M/i));
ret += (sum_MU[j]-sum_MU[i-1]) * sum_D[N/i] * sum_D[M/i];
}
return ret;
}
}
using namespace Mobius;
int main ()
{
init();
int T, n, m;
scanf("%d", &T);
while(T--)
{
scanf("%d%d", &n, &m);
printf("%lld\n", calc(n, m));
}
}

[SDOI2015][bzoj 3994][Luogu P3327] 约数个数和 (莫比乌斯反演)的更多相关文章

  1. P3327 [SDOI2015]约数个数和 莫比乌斯反演

    P3327 [SDOI2015]约数个数和 莫比乌斯反演 链接 luogu 思路 第一个式子我也不会,luogu有个证明,自己感悟吧. \[d(ij)=\sum\limits_{x|i}\sum\li ...

  2. BZOJ 3994: [SDOI2015]约数个数和 [莫比乌斯反演 转化]

    2015 题意:\(d(i)\)为i的约数个数,求\(\sum\limits_{i=1}^n \sum\limits_{j=1}^m d(ij)\) \(ij\)都爆int了.... 一开始想容斥一下 ...

  3. luogu P3327 [SDOI2015]约数个数和 莫比乌斯反演

    题面 我的做法基于以下两个公式: \[[n=1]=\sum_{d|n}\mu(d)\] \[\sigma_0(i*j)=\sum_{x|i}\sum_{y|j}[gcd(x,y)=1]\] 其中\(\ ...

  4. BZOJ 3994: [SDOI2015]约数个数和3994: [SDOI2015]约数个数和 莫比乌斯反演

    https://www.lydsy.com/JudgeOnline/problem.php?id=3994 https://blog.csdn.net/qq_36808030/article/deta ...

  5. [BZOI 3994] [SDOI2015]约数个数和(莫比乌斯反演+数论分块)

    [BZOI 3994] [SDOI2015]约数个数和 题面 设d(x)为x的约数个数,给定N.M,求\(\sum _{i=1}^n \sum_{i=1}^m d(i \times j)\) T组询问 ...

  6. 洛谷P3327 [SDOI2015]约数个数和(莫比乌斯反演)

    题目描述 设d(x)为x的约数个数,给定N.M,求 \sum^N_{i=1}\sum^M_{j=1}d(ij)∑i=1N​∑j=1M​d(ij) 输入输出格式 输入格式: 输入文件包含多组测试数据.第 ...

  7. 【BZOJ3994】[SDOI2015]约数个数和 莫比乌斯反演

    [BZOJ3994][SDOI2015]约数个数和 Description  设d(x)为x的约数个数,给定N.M,求   Input 输入文件包含多组测试数据. 第一行,一个整数T,表示测试数据的组 ...

  8. [SDOI2015][bzoj3994] 约数个数和 [莫比乌斯反演]

    题面: 传送门 思路: 首先,我们需要证明一个结论:d(i*j)等于sigma(gcd(x,y)==1),其中x为i的约数,y为j的约数 对于nm的每一个质因子pi分别考虑,设n = pi^ai + ...

  9. BZOJ3994: [SDOI2015]约数个数和(莫比乌斯反演)

    Description  设d(x)为x的约数个数,给定N.M,求     Input 输入文件包含多组测试数据. 第一行,一个整数T,表示测试数据的组数. 接下来的T行,每行两个整数N.M. Out ...

随机推荐

  1. 修改主机名和修改主机映射和ssh免登陆

    1.修改主机名 vim /etc/sysconfig/network NETWORKING=yes HOSTNAME=cc3 2.修改主机映射 vi /etc/hosts 127.0.0.1 loca ...

  2. (转)FFMPEG 实现 YUV,RGB各种图像原始数据之间的转换(swscale)

    雷霄骅分类专栏: FFMPEG FFmpeg 本文链接:https://blog.csdn.net/leixiaohua1020/article/details/14215391 FFMPEG中的sw ...

  3. FPS 游戏实现GDI透视

    FPS游戏可以说一直都比较热门,典型的代表有反恐精英,穿越火线,绝地求生等,基本上只要是FPS游戏都会有透视挂的存在,而透视挂还分为很多种类型,常见的有D3D透视,方框透视,还有一些比较高端的显卡透视 ...

  4. Java8新特性 - 并行流与串行流

    并行流就是把一个内容分成多个数据块,并用不同的线程分别处理每个数据块的流. Java8中将并行进行了优化,我们可以很容易的对数据进行并行操作.Stream API可以声明性地通过parallel()和 ...

  5. hdu 2181.。。。

    哈密顿绕行世界问题 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...

  6. springboot笔记04——读取配置文件+使用slf4j日志

    前言 springboot常用的配置文件有yml和properties两种,当然有必要的时候也可以用xml.我个人更加喜欢用yml,所以我在这里使用yml作为例子.yml或properties配置文件 ...

  7. 3.Ubuntu/Deepin下安装Monaco/Menlo字体

    前段时间在一家公司实习,让IT给电脑安装了Ubuntu系统,用着挺好,但总感觉字体不太好看,网上小伙伴说Monaco字体不错,所以计划安装试试. 看了好多教程,不得不说,一些教程走下来真心是装不成功, ...

  8. elementui限制开始日期和结束日期

    项目需求:开始日期和结束日期 禁用当前日期之前的日期.同时结束日期 禁用开始日期之前的日期 <div class='startTime'> 开始时间:<el-date-picker ...

  9. 13 个 JS 数组精简技巧

    来自 https://juejin.im/post/5db62f1bf265da4d560906ab 侵删 数组是 JS 最常见的一种数据结构,咱们在开发中也经常用到,在这篇文章中,提供一些小技巧,帮 ...

  10. 将网址url中的参数转化为JSON格式的两种方法

    在我们进入主题前,我先先看下获取网址URL的方法: window.location.href // 设置或获取整个URL为字符串 window.location.hash // 设置或获取href属性 ...