题目

设d(x)为x的约数个数,给定N、M,求\(\sum_{i = 1}^{N} \sum_{j = 1}^{M} d(ij)\)

输入格式

输入文件包含多组测试数据。第一行,一个整数T,表示测试数据的组数。接下来的T行,每行两个整数N、M。

输出格式

T行,每行一个整数,表示你所求的答案。

输入样例

2

7 4

5 6

输出样例

110

121

提示

1<=N, M<=50000

1<=T<=50000

题解

好神的题【是我太弱吧】

首先上来就伤结论。。

题目所求

\[ans = \sum_{i = 1}^{N} \sum_{j = 1}^{M} d(ij)
\]

有一个这样的结论:

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

那么就转化为了:

\[ans =\sum_{i = 1}^{N} \sum_{j = 1}^{M} \sum_{x|i}\sum_{y|j} [gcd(x,y) == 1]
\]

我们考虑对于每一对互质的x、y,x会被枚举\(\lfloor \frac{N}{x} \rfloor\)次,y会被枚举\(\lfloor \frac{M}{y} \rfloor\)次

所以有

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

那么可以进行莫比乌斯反演了

令

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

\[F(n) = \sum_{i = 1}^{N} \sum_{j = 1}^{M} \lfloor \frac{N}{i} \rfloor \lfloor \frac{M}{j} \rfloor [n | gcd(i,j)]
\]

那么有

\[\begin{aligned}
F(d) &= (\sum_{i = 1}^{N}\lfloor \frac{N}{i} \rfloor) * (\sum_{j = 1}^{M} \lfloor \frac{M}{j} \rfloor) [d | gcd(i,j)] \\
&= (\sum_{i = 1}^{\lfloor \frac{N}{d} \rfloor}\lfloor \frac{N}{id} \rfloor) * (\sum_{j = 1}^{\lfloor \frac{M}{d} \rfloor} \lfloor \frac{M}{jd} \rfloor) \\
&= (\sum_{i = 1}^{\lfloor \frac{N}{d} \rfloor}\lfloor \frac{\lfloor \frac{N}{d} \rfloor}{i} \rfloor) * (\sum_{j = 1}^{\lfloor \frac{M}{d} \rfloor} \lfloor \frac{\lfloor \frac{M}{d} \rfloor}{j} \rfloor)
\end{aligned}
\]

其中\(\sum_{i = 1}^{N}\lfloor \frac{N}{i} \rfloor\)可以\(O(n\sqrt{n})\)预处理出,我们记为\(sum(n)\)

那么

\[F(n) = sum(\lfloor \frac{N}{n} \rfloor) * sum(\lfloor \frac{M}{n} \rfloor)
\]

\[ans = f(1) = \sum_{d = 1}^{N} \mu(d) * F(d) = \sum_{d} \mu(d) sum(\lfloor \frac{N}{d} \rfloor) * sum(\lfloor \frac{M}{d} \rfloor)
\]

分块计算

复杂度\(O(T\sqrt{N} + N\sqrt{N})\)

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long int
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define BUG(s,n) for (int i = 1; i <= (n); i++) cout<<s[i]<<' '; puts("");
using namespace std;
const int maxn = 50005,maxm = 100005,INF = 1000000000;
inline int read(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57) {if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57) {out = (out << 3) + (out << 1) + c - '0'; c = getchar();}
return out * flag;
}
int prime[maxn],primei,mu[maxn],isn[maxn];
LL sum[maxn];
void init(){
mu[1] = 1;
for (int i = 2; i < maxn; i++){
if (!isn[i]) prime[++primei] = i,mu[i] = -1;
for (int j = 1; j <= primei && i * prime[j] < maxn; j++){
isn[i * prime[j]] = true;
if (i % prime[j] == 0){mu[i * prime[j]] = 0; break;}
mu[i * prime[j]] = -mu[i];
}
}
for (int i = 1; i < maxn; i++) mu[i] += mu[i - 1];
for (int n = 1,nxt; n <= 50000; n++){
for (int i = 1; i <= n; i = nxt + 1){
nxt = n / (n / i);
sum[n] += (LL)(nxt - i + 1) * (n / i);
}
}
}
int main(){
init();
int T = read(),n,m;
while (T--){
n = read(); m = read();
if (n > m) swap(n,m);
LL ans = 0; int nxt;
for (int i = 1; i <= n; i = nxt + 1){
nxt = min(n / (n / i),m / (m / i));
ans += sum[n / i] * sum[m / i] * (mu[nxt] - mu[i - 1]);
}
printf("%lld\n",ans);
}
return 0;
}

洛谷P3327 [SDOI2015]约数个数和 【莫比乌斯反演】的更多相关文章

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

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

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

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

  3. 洛谷P3327 - [SDOI2015]约数个数和

    Portal Description 共\(T(T\leq5\times10^4)\)组数据.给出\(n,m(n,m\leq5\times10^4)\),求\[\sum_{i=1}^n\sum_{j= ...

  4. 洛谷 P3327 [SDOI2015]约数个数和 || Number Challenge Codeforces - 235E

    https://www.luogu.org/problemnew/show/P3327 不会做. 去搜题解...为什么题解都用了一个奇怪的公式?太奇怪了啊... 公式是这样的: $d(xy)=\sum ...

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

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

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

    传送门 公式太长了……我就直接抄一下这位大佬好了……实在懒得打了 首先据说$d(ij)$有个性质$$d(ij)=\sum_{x|i}\sum_{y|j}[gcd(x,y)=1]$$ 我们所求的答案为$ ...

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

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

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

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

  9. LOJ #2185 / 洛谷 P3329 - [SDOI2015]约数个数和(莫比乌斯函数)

    LOJ 题面传送门 / 洛谷题面传送门 题意: 求 \(\sum\limits_{i=1}^n\sum\limits_{j=1}^md(ij)\),\(d(x)\) 为 \(x\) 的约数个数. \( ...

随机推荐

  1. UVA 1615 Highway 高速公路 (区间选点)

    题意:在一条线段上选出尽量少的点,使得和所有给出的n个点距离不超过D. 分别计算出每个点在线段的满足条件的区间,然后就转化成了区间选点的问题了,按照右端点排序,相同时按照左端点排序,按照之前的排序一定 ...

  2. [Java] 新手快速就业需要掌握的知识点

    目的:主要是分享下日常工作中使用到的技术点,根据二八定律快速掌握使用知识点,先就业再沉淀去积累经验.(个人建议仅供参考) 背景:目前一般来说,都是前后端分离.你只需要提供接口给前端,他来处理就可以了, ...

  3. 使用ImageList组件制作动画图片

    实现效果: 知识运用: Timer组件的Enabled属性  Tick事件 PictureBox控件的Image属性 ImageList组件的Images属性 实现代码: private void F ...

  4. C-基础:形参char *&p与char *p

    char* &p:以引用传递的方式传指针char* p: 以值传递的方式传指针

  5. mysql grant 用户权限说明

    mysql grant 用户权限说明 Mysql 有多个个权限?经常记不住,今天总结一下,看后都能牢牢的记在心里啦!! 很明显总共28个权限:下面是具体的权限介绍:转载的,记录一下: 一.权限表 my ...

  6. 2d游戏中求出一个向量的两个垂直向量

    function cc.exports.VerticalVector(vec)--求出两个垂直向量 local result = {} result[1] = cc.p(vec.y/vec.x,-1) ...

  7. Pig Latin-freecodecamp算法题目

    Pig Latin 1.要求 Pig Latin把一个英文单词的第一个辅音或辅音丛(consonant cluster)移到词尾,然后加上后缀 "ay". 如果单词以元音开始,你只 ...

  8. Linux常用文档操作命令--2

    4.文档压缩与解压操作 在Linux中常见的压缩文件有:*.tar.gz.*.tgz.*.gz.*.Z.*bz2等.其每种不同的压缩文件对印的压缩和解压命令也不同. *.tar.gz :tar程序打包 ...

  9. Ubuntu 16.04中安装谷歌Chrome浏览器

    1.进入 Ubuntu 16.04 桌面,按下 Ctrl + Alt + t 键盘组合键,启动终端. 2.在终端中,输入以下命令: sudo wget https://repo.fdzh.org/ch ...

  10. (转).gitignore详解

    本文转自http://sentsin.com/web/666.html 今天讲讲Git中非常重要的一个文件——.gitignore. 首先要强调一点,这个文件的完整文件名就是“.gitignore”, ...