Brief Description

计算\(\sum_{i\leqslant n}\sum_{j\leqslant m}\sigma_0(ij)\).

Algorithm Design

首先证明一个结论

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

我们不显式地证明它, 仅仅直观地考虑每个质数对于答案的贡献就好.

有了这个结论我们开始推式子:

\[\begin{aligned}
\sum_{i\leqslant n}\sum_{j\leqslant m}\sigma_0(ij) & = \sum_{i\leqslant n}\sum_{j\leqslant m} \sum_{a|i} \sum_{b|j} [(i,j)=1]\\ & =\sum_{i\leqslant n}\sum_{j\leqslant m}\sum_{a|i}\sum_{b|j}\sum_{x|(i,j)}\mu(x)\\& =\sum_{i\leqslant n}\sum_{j \leqslant m}\sum_{x|i+j}\mu(x)\sigma_0(\frac ix)\sigma_0(\frac jx) \\ &=\sum_{x \leqslant n} \mu(x)\sum_{i \leqslant \lfloor \frac nx \rfloor} \sigma_0(i)\sum_{j \leqslant \lfloor \frac mx \rfloor}\sigma_0(j)
\end{aligned}
\]

有了最后的式子, 我们就可以开始乱搞了.

复杂度\(O(n+T\sqrt n)\)

Code

#include <algorithm>
#include <cctype>
#include <cstdio>
#define ll long long
const int maxn = 50000 + 10;
int prime[maxn], tot;
int mu[maxn], sigma[maxn], summu[maxn];
ll sumsigma[maxn];
bool check[maxn];
int read() {
int x = 0, f = 1;
char ch = getchar();
while (!isdigit(ch)) {
if (ch == '-')
f = -1;
ch = getchar();
}
while (isdigit(ch)) {
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
void shake() {
int minPrimeCnt[maxn];
mu[1] = 1, sigma[1] = 1;
for (int i = 2; i < maxn; i++) {
if (!check[i]) {
prime[tot++] = i;
mu[i] = -1;
sigma[i] = 2;
minPrimeCnt[i] = 1;
}
for (int j = 0; j < tot; j++) {
int x = i * prime[j];
if (x >= maxn)
break;
check[x] = 1;
if (i % prime[j] == 0) {
mu[x] = 0;
minPrimeCnt[x] = minPrimeCnt[i] + 1;
sigma[x] = sigma[i] / (minPrimeCnt[i] + 1) * (minPrimeCnt[x] + 1);
break;
} else {
mu[x] = -mu[i];
sigma[x] = sigma[i] << 1;
minPrimeCnt[x] = 1;
}
}
}
summu[0] = 0;
for (int i = 1; i < maxn; i++)
summu[i] = summu[i - 1] + mu[i];
for (int i = 1; i < maxn; i++)
sumsigma[i] = sumsigma[i - 1] + sigma[i];
}
ll F(int n, int m) {
if (n > m)
std::swap(n, m);
ll ans = 0;
for (int i = 1, last = 1; i <= n; i = last + 1) {
last = std::min(n / (n / i), m / (m / i));
ans += (summu[last] - summu[i - 1]) * sumsigma[n / i] * sumsigma[m / i];
}
return ans;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("input", "r", stdin);
#endif
shake();
int kase = read();
while (kase--) {
int n = read(), m = read();
printf("%lld\n", F(n, m));
}
return 0;
}

[bzoj3994][SDOI2015]约数个数和-数论的更多相关文章

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

    P3327 [SDOI2015]约数个数和 神犇题解(转) 无话可补 #include<iostream> #include<cstdio> #include<cstri ...

  2. BZOJ3994: [SDOI2015]约数个数和

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

  3. bzoj千题计划203:bzoj3994: [SDOI2015]约数个数和

    http://www.lydsy.com/JudgeOnline/problem.php?id=3994 设d(x)为x的约数个数,给定N.M,求 用到的一个结论: 证明: 枚举n的约数i,枚举m的约 ...

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

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

  5. bzoj3994: [SDOI2015]约数个数和(反演+结论?!)

    这题做的历程堪称惊心动魄 刚刚学了莫比乌斯反演的我高高兴兴的和cbx一起反演式子 期间有突破,有停滞,有否定 然后苟蒻的我背着cbx偷偷打开了题解 看到了 我...... 去你的有个性质啊(当然还是自 ...

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

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

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

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

  8. 【BZOJ3994】约数个数和(莫比乌斯反演)

    [BZOJ3994]约数个数和(莫比乌斯反演) 题面 求\[\sum_{i=1}^n\sum_{j=1}^md(ij)\] 多组数据\((<=50000组)\) \(n,m<=50000\ ...

  9. BZOJ_3994_[SDOI2015]约数个数和_莫比乌斯反演

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

随机推荐

  1. 谷歌js编码规范解析

    http://alloyteam.github.io/JX/doc/specification/google-javascript.xm 阅读了谷歌js编码规范,我发现了很多,js的里面很多要注意的问 ...

  2. 分布式资源调度--YARN框架

    YARN产生背景 YARN是Hadoop2.x才有的,所以在介绍YARN之前,我们先看一下MapReduce1.x时所存在的问题: 单点故障 节点压力大 不易扩展 MapReduce1.x时的架构如下 ...

  3. 用tensorflow实现自然语言处理——基于循环神经网络的神经语言模型

    自然语言处理和图像处理不同,作为人类抽象出来的高级表达形式,它和图像.声音不同,图像和声音十分直觉,比如图像的像素的颜色表达可以直接量化成数字输入到神经网络中,当然如果是经过压缩的格式jpeg等必须还 ...

  4. DP入门(1)——数字三角形问题

    一.问题描述 如上图所示,有一个由非负整数组成的三角形,第一行只有一个数,除了最下行之外每个数的左下方和右下方各有一个数.现请你在此数字三角形中寻找一条从首行到最下行的路径,使得路径上所经过的数字之和 ...

  5. JavaScript Map数据结构

    Array.prototype.remove = function (s) { for (var i = 0; i < this.length; i++) { if (s == this[i]) ...

  6. C++中getline()函数简介

    有时我们希望能在最终得到的字符中保留输入时的空白符,这时应该用getline()函数代替原来的>>运算符. 下面是使用getline读取一整行的示例代码: #include<iost ...

  7. 【Linux】Linux修改openfile和max user processes?

    #当时测试虚机为centos7.4版本: # 在/etc/security/limits.conf文件末尾添加如下命令: *     soft     nproc   1314 *     hard  ...

  8. [C/C++] extern关键字详解以及与static、const区别

    extern用法详解: 1. 声明外部实体 声明外部全局变量或对象,一般用于头文件中,表示在其它编译单元内定义的变量,链接时进行外部链接,如: extern int ivalue; 此时的extern ...

  9. SpringBoot2.0

    建立可执行的Jars和Wars bootJar用于构建可执行的Jar: bootWar用于构建可执行的war. application.properties 不启动web服务器 spring.main ...

  10. sqoop将oracle数据导入hdfs集群

    使用sqoop将oracle数据导入hdfs集群 集群环境: hadoop1.0.0 hbase0.92.1 zookeeper3.4.3 hive0.8.1 sqoop-1.4.1-incubati ...