[SDOI2015]约数个数和 莫比乌斯反演
题解:
为什么SDOI这么喜欢莫比乌斯反演,,,
首先有一个结论$$d(ij) = \sum_{x|i}\sum_{y|j}[gcd(x, y) == 1]$$
为什么呢?
首先,可以看做从两个数中分别取一些不重叠的质数的$k_{i}$次方,组成新数的方案数。
那如果有需要重叠的部分怎么办?
可以看做全都在第一个or第二个数中取。
但是一个数的次数不够怎么办呢?
相当于以1为媒介,可以简介统计到这些情况
比如$2^{3} \cdot 2^{2} = 2^{5}$可以看成$1, 2^{3}$ + $1, 2^{2}$,这样就可以做到分别枚举了指数从1到5的情况了;
$$ans = \sum_{i = 1}^{n}\sum_{j = 1}^{m}\sum_{x | i}\sum_{y | j}[gcd(x, y) == 1]$$
$$ans = \sum_{x = 1}^{n}\sum_{y = 1}^{m} \lfloor{\frac{n}{x}}\rfloor \lfloor{\frac{m}{y}}\rfloor [gcd(x, y) == 1]$$<---改成枚举x和y,然后统计有多少对i,j中分别含有因数x,y
设$$f(d) = \sum_{x = 1}^{n}\sum_{y = 1}^{m} \lfloor{\frac{n}{x}}\rfloor \lfloor{\frac{m}{y}}\rfloor [gcd(x, y) == d]$$, $$g(x) = \sum_{x | d}^{min(n, m)}{f(d)}$$
那么$ans = f(1)$
反演一下得到:$$f(n) = \sum_{n | d}\mu(\frac{d}{n}) \cdot g(d)$$
接下来就是怎么求$g(d)$了。
$$g(d) = \sum_{x = 1}^{n}\sum_{y = 1}^{m} \lfloor{\frac{n}{x}}\rfloor \lfloor{\frac{m}{y}}\rfloor [d | gcd(x, y)]$$
$d | gcd(x, y)$ ---> $d | x + d | y$ ,因为$x | n + y | m$ ---> $d | n + d | m$
所以枚举$d_{i}$就符合条件了,$\lfloor{\frac{n}{dx}}\rfloor$ ---> $dx$倍数的个数,即有多少i,j的搭配是可以满足$[d|gcd(x, y)]$的
$$g(d) = \sum_{x = 1}^{ \lfloor{\frac{n}{d}}\rfloor }\sum_{y = 1}^{ \lfloor{\frac{m}{d}}\rfloor } \lfloor{\frac{n}{dx}}\rfloor \lfloor{\frac{m}{dy}}\rfloor$$
于是现在就是要求$f(1)$
$$f(1) = \sum_{d = 1}^{min(n, m)}{\mu(\frac{d}{1})g(d)}$$
$$= \sum_{d = 1}^{min(n, m)}{\mu(d)g(d)}$$
$$= \sum_{d = 1}^{min(n, m)}{\mu(d) \cdot \sum_{x = 1}^{ \lfloor{\frac{n}{d}}\rfloor }\sum_{y = 1}^{ \lfloor{\frac{m}{d}}\rfloor } \lfloor{\frac{n}{dx}}\rfloor \lfloor{\frac{m}{dy}}\rfloor}$$
这个式子可以整数分块。
设$N = \frac{n}{d}$, $M = \frac{m}{d}$,那么
$$= \sum_{d = 1}^{min(n, m)}{\mu(d) \cdot \sum_{x = 1}^{ N }\sum_{y = 1}^{ M } \lfloor{\frac{N}{x}}\rfloor \lfloor{\frac{M}{y}}\rfloor}$$
$$= \sum_{d = 1}^{min(n, m)}{\mu(d) \cdot \sum_{x = 1}^{ N}{\lfloor{\frac{N}{x}}\rfloor} \sum_{y = 1}^{M} {\lfloor{\frac{M}{y}}\rfloor}}$$
而$N = \lfloor{\frac{n}{d}}\rfloor$, $M = \lfloor{\frac{m}{d}}\rfloor$有很多相同的区间段,所以可以整数分块求。
#include<bits/stdc++.h>
using namespace std;
#define R register int
#define AC 50100
#define ac 50000
#define LL long long
int n, m, tot, t;
LL ans;
int prime[AC];
LL mu[AC], s[AC];
bool z[AC]; inline int read()
{
int x = ;char c = getchar();
while(c > '' || c < '') c = getchar();//error!!!又一次打错了读入优化。。。是||啊
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x;
} void pre()
{
int x;
mu[] = ;
for(R i = ; i <= ac; i++)
{
if(!z[i]) prime[++tot] = i, mu[i] = -;
for(R j = ; j <= tot; j++)
{
x = prime[j];
if(x * i > ac) break;
z[x * i] = true;
if(!(i % x)) break;
mu[i * x] = -mu[i];
}
}
for(R i = ; i <= ac; i++) mu[i] += mu[i-];
int pos;
for(R i = ; i <= ac; i++)
{
for(R j = ; j <= i; j = pos + )
{
pos = i / (i / j);
s[i] += (LL)(i / j) * (LL)(pos - j + );
}
}
// for(R i = 1; i <= 30; i++) printf("%lld\n", s[i]);
} void work()
{
t = read();
while(t--)
{
n = read(), m = read(), ans = ;
//scanf("%d%d", &n, &m);ans = 0;
int pos, b = min(n, m);
for(R i = ; i <= b; i = pos + )
{
pos = min(n / (n / i), m / (m / i));
ans += (mu[pos] - mu[i - ]) * s[n / i] * s[m / i];
}
printf("%lld\n", ans);
}
} int main()
{
// freopen("in.in", "r", stdin);
pre();
work();
// fclose(stdin);
return ;
}
[SDOI2015]约数个数和 莫比乌斯反演的更多相关文章
- P3327 [SDOI2015]约数个数和 莫比乌斯反演
P3327 [SDOI2015]约数个数和 莫比乌斯反演 链接 luogu 思路 第一个式子我也不会,luogu有个证明,自己感悟吧. \[d(ij)=\sum\limits_{x|i}\sum\li ...
- 【BZOJ3994】[SDOI2015]约数个数和 莫比乌斯反演
[BZOJ3994][SDOI2015]约数个数和 Description 设d(x)为x的约数个数,给定N.M,求 Input 输入文件包含多组测试数据. 第一行,一个整数T,表示测试数据的组 ...
- [BZOI 3994] [SDOI2015]约数个数和(莫比乌斯反演+数论分块)
[BZOI 3994] [SDOI2015]约数个数和 题面 设d(x)为x的约数个数,给定N.M,求\(\sum _{i=1}^n \sum_{i=1}^m d(i \times j)\) T组询问 ...
- luogu P3327 [SDOI2015]约数个数和 莫比乌斯反演
题面 我的做法基于以下两个公式: \[[n=1]=\sum_{d|n}\mu(d)\] \[\sigma_0(i*j)=\sum_{x|i}\sum_{y|j}[gcd(x,y)=1]\] 其中\(\ ...
- BZOJ 3994: [SDOI2015]约数个数和 [莫比乌斯反演 转化]
2015 题意:\(d(i)\)为i的约数个数,求\(\sum\limits_{i=1}^n \sum\limits_{j=1}^m d(ij)\) \(ij\)都爆int了.... 一开始想容斥一下 ...
- BZOJ 3994: [SDOI2015]约数个数和3994: [SDOI2015]约数个数和 莫比乌斯反演
https://www.lydsy.com/JudgeOnline/problem.php?id=3994 https://blog.csdn.net/qq_36808030/article/deta ...
- 洛谷P3327 [SDOI2015]约数个数和(莫比乌斯反演)
题目描述 设d(x)为x的约数个数,给定N.M,求 \sum^N_{i=1}\sum^M_{j=1}d(ij)∑i=1N∑j=1Md(ij) 输入输出格式 输入格式: 输入文件包含多组测试数据.第 ...
- BZOJ3994: [SDOI2015]约数个数和(莫比乌斯反演)
Description 设d(x)为x的约数个数,给定N.M,求 Input 输入文件包含多组测试数据. 第一行,一个整数T,表示测试数据的组数. 接下来的T行,每行两个整数N.M. Out ...
- BZOJ.3994.[SDOI2015]约数个数和(莫比乌斯反演)
题目链接 \(Description\) 求\[\sum_{i=1}^n\sum_{j=1}^md(ij)\] \(Solution\) 有结论:\[d(nm)=\sum_{i|d}\sum_{j|d ...
随机推荐
- SpringBoot-01:什么是SpringBoot?
------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- SpringBoot: Spring Boot可以轻松创建独立的,生产级的基于Spring的应用程序,您可以“ ...
- Mysql 8.0.* zip版本 windows安装
一,MySQL8.0.*zip版本安装步骤. 1,下载 https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.15-winx64.zip 注现 ...
- VIM第七版
ZZ:退出并保存 e!:退回到上次保存时的样子 cw:修改单词(自动进入插入模式) cc:修改一整行的内容 cs:修改一个词(自动进入插入模式) .:可以重复上一个命令 J:将下一行内容合并到本行末尾 ...
- lintcode 二叉树中序遍历
/** * Definition of TreeNode: * class TreeNode { * public: * int val; * TreeNode *left, *right; * Tr ...
- 爬虫2.1-scrapy框架-两种爬虫对比
目录 scrapy框架-两种爬虫对比和大概流程 1. 传统spider爬虫 2. crawl型爬虫 3. 循环页面请求 4. scrapy框架爬虫的大致流程 scrapy框架-两种爬虫对比和大概流程 ...
- "Generative Adversarial Nets" Notes
- Ian J.Goodfellow 中文翻译:https://blog.csdn.net/wspba/article/details/54577236 代码实现:https://github.com ...
- 【转】Expressions versus statements in JavaScript
原文地址:http://www.2ality.com/2012/09/expressions-vs-statements.html Update 2012-09-21: New in Sect. 4: ...
- node.js安装部署
node js 安装部署学习 CentOS 下安装 Node.js 1.下载源码,你需要在https://nodejs.org/en/download/下载最新的Nodejs版本,链接: http ...
- k邻近算法理解及代码实现
github:代码实现 本文算法均使用python3实现 1 KNN KNN(k-nearest neighbor, k近邻法),故名思议,是根据最近的 $ k $ 个邻居来判断未知点属于哪个类别 ...
- 透过汇编另眼看世界之DLL导出函数调用
前言:我一直对DLL技术充满好奇,一方面是因为我对DLL的导入/导出机制还不是特别的了解,另一面是因为我发现:DLL技术在Windows平台下占有重要的地位,几乎所有的Win32 API都是以导出函数 ...