【Luogu P2257】YY 的 GCD
题目
求:
\]
有 \(T\) 组数据, \(T\le 10^4, n, m\le 10^7\)
分析
莫比乌斯反演:
& \sum_{i = 1}^n \sum_{j = 1}^m [\gcd(i, j) \in \mathbb P]\\
= & \sum_{p \in \mathbb P, p\le \min(n, m)}\sum_{i = 1}^n \sum_{j = 1}^m [\gcd(i, j) = p]\\
\end{align*}
\]
设 \(f(x) = \sum_{i = 1}^n \sum_{j = 1}^m [\gcd(i, j) = x]\), $F(x) = \sum_{i = 1}^n \sum_{j = 1}^m [x\ |\gcd(i, j)]=\left\lfloor \frac nx\right\rfloor\left\lfloor \frac mx\right\rfloor $
则有:
\]
故有:
& \sum_{p \in \mathbb P, p\le \min(n, m)}\sum_{i = 1}^n \sum_{j = 1}^m [\gcd(i, j) = p]\\
= & \sum_{p \in \mathbb P, p\le \min(n, m)} f(p) \\
= & \sum_{p \in \mathbb P, p\le \min(n, m)} \sum_{p|d,d\le \min(n, m)} \mu(\frac dp) \left\lfloor \frac nd\right\rfloor\left\lfloor \frac md\right\rfloor \\
= & \sum_{d = 1}^{\min(n, m)} \sum_{p \in \mathbb P,p|d, p\le \min(n, m)} \mu(\frac dp) \left\lfloor \frac nd\right\rfloor\left\lfloor \frac md\right\rfloor \\
= & \sum_{d = 1}^{\min(n, m)} \left\lfloor \frac nd\right\rfloor\left\lfloor \frac md\right\rfloor \sum_{p \in \mathbb P,p|d, p\le \min(n, m)} \mu(\frac dp)
\end{align*}
\]
设 $g(x) = \sum_{p \in \mathbb P,p|x, p\le \min(n, m)} \mu(\frac xp) $
求法(暴力出奇迹, 经测试下面算法耗时不到 \(0.5 s\)):
void get_g(int n) {
for(int i = 1; i <= n; i++) {
int tmp = i;
while(tmp != 1) {
g[i] += mobius[i / s_factor[tmp]];
int p = s_factor[tmp];
if(tmp % (p * p) == 0) break;
for(; tmp % p == 0; tmp /= p);
}
g_prefix[i] = g_prefix[i - 1] + g[i];
}
}
有上式等于:
\]
对于 \(\left\lfloor \frac nd\right\rfloor\left\lfloor \frac md\right\rfloor\) 相同的值整除分块即可.
代码
#include <bits/stdc++.h>
typedef long long Int64;
const int kMaxSize = 1e7 + 5;
int s_factor[kMaxSize], prime[kMaxSize], mobius[kMaxSize], g[kMaxSize],
g_prefix[kMaxSize], prime_tot = 0;
bool isn_prime[kMaxSize];
void euler_sieve(int n) {
mobius[1] = 1;
isn_prime[0] = isn_prime[1] = true;
for(int i = 2; i <= n; i++) {
if(!isn_prime[i]) {
prime[prime_tot++] = i;
s_factor[i] = i;
mobius[i] = -1;
}
for(int j = 0; j < prime_tot && i * prime[j] <= n; j++) {
isn_prime[i * prime[j]] = true;
s_factor[i * prime[j]] = prime[j];
mobius[i * prime[j]] = -mobius[i];
if(i % prime[j] == 0) {
mobius[i * prime[j]] = 0;
break;
}
}
}
}
void get_g(int n) {
for(int i = 1; i <= n; i++) {
int tmp = i;
while(tmp != 1) {
g[i] += mobius[i / s_factor[tmp]];
int p = s_factor[tmp];
if(tmp % (p * p) == 0) break;
for(; tmp % p == 0; tmp /= p);
}
g_prefix[i] = g_prefix[i - 1] + g[i];
}
}
int main() {
euler_sieve(1e7);
get_g(1e7);
int t;
scanf("%d", &t);
while(t--) {
int n, m;
Int64 ans = 0;
scanf("%d%d", &n, &m);
if(!n) break;
for(int l = 1, r; l <= n && l <= m; l = r + 1) {
r = std::min(n / (n / l), m / (m / l));
ans += (Int64)(n / l) * (m / l) * (g_prefix[r] - g_prefix[l - 1]);
}
printf("%lld\n", ans);
}
return 0;
}
【Luogu P2257】YY 的 GCD的更多相关文章
- [Luogu P2257] YY的GCD (莫比乌斯函数)
题面 传送门:洛咕 Solution 推到自闭,我好菜啊 显然,这题让我们求: \(\large \sum_{i=1}^{n}\sum_{j=1}^{m}[gcd(i,j)\in prime]\) 根 ...
- Luogu P2257 YY的GCD
莫比乌斯反演第一题.莫比乌斯反演入门 数论题不多BB,直接推导吧. 首先,发现题目所求\(ans=\sum_{i=1}^n\sum_{j=1}^m [\gcd(i,j)=prime]\) 考虑反演,我 ...
- 【题解】Luogu P2257 YY的GCD
原题传送门 这题需要运用莫比乌斯反演(懵逼钨丝繁衍) 显然题目的答案就是\[ Ans=\sum_{i=1}^N\sum_{j=1}^M[gcd(i,j)=prime]\] 我们先设设F(n)表示满足\ ...
- Luogu P2257 YY的GCD 莫比乌斯反演
第一道莫比乌斯反演...$qwq$ 设$f(d)=\sum_{i=1}^n\sum_{j=1}^m[gcd(i,j)==d]$ $F(n)=\sum_{n|d}f(d)=\lfloor \frac{N ...
- 洛谷 P2257 YY的GCD
洛谷 P2257 YY的GCD \(solution:\) 这道题完全跟[POI2007]ZAP-Queries (莫比乌斯反演+整除分块) 用的一个套路. 我们可以列出答案就是要我们求: \(ans ...
- P2257 YY的GCD
P2257 YY的GCD 题目描述 神犇YY虐完数论后给傻×kAc出了一题 给定N, M,求1<=x<=N, 1<=y<=M且gcd(x, y)为质数的(x, y)有多少对 k ...
- 题解 P2257 YY的GCD
P2257 YY的GCD 解题思路 果然数论的题是真心不好搞. 第一个莫比乌斯反演的题,好好推一下式子吧..(借鉴了blog) 我们要求的答案就是\(Ans=\sum\limits_{i=1}^{n} ...
- P2257 YY的GCD (莫比乌斯反演)
[题目链接] https://www.luogu.org/problemnew/show/P2257 // luogu-judger-enable-o2 /* -------------------- ...
- 洛谷 - P2257 - YY的GCD - 莫比乌斯反演 - 整除分块
https://www.luogu.org/problemnew/show/P2257 求 \(n,m\) 中 \(gcd(i,j)==p\) 的数对的个数 求 $\sum\limits_p \sum ...
- 洛谷 P2257 YY的GCD 题解
原题链接 庆祝: 数论紫题 \(T4\) 达成! 莫比乌斯 \(T1\) 达成! yy 真是个 神犇 前记 之前我觉得: 推式子,直接欧拉筛,筛出个 \(\phi\),然后乱推 \(\gcd\) 就行 ...
随机推荐
- MPMoviePlayerViewController和MPMoviePlayerController的使用
ios播放视频文件一般使用 MPMoviePlayerViewController 和 MPMoviePlayerController.前者是一个view,后者是个Controller.差别就是MPM ...
- HDU(3560)成环,并查集
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3560 并查集查有几个块,修改了之前我的一个方法(用什么map),直接判断根节点的id是i的个数. 然后 ...
- Oracle数据库几种启动方式及查询当前状态
Oracle数据库几种启动方式 1.startup nomount: 非安装启动,这种方式下启动可执行:重建控制文件.重建数据库,读取init.ora文件,启动instance,即启动SGA和后台进程 ...
- app上线
不管第一次还是第二次APP上线都需要三样东西:开发者证书,appID,描述文件
- Python 3 collections.defaultdict() 与 dict的使用和区别
综述: 这里的defaultdict(function_factory)构建的是一个类似dictionary的对象,其中keys的值,自行确定赋值,但是values的类型,是function_fact ...
- sql查询字段值长度判断是否18位
SELECT * FROM 表名 WHERE LENGTH(字段)= OR 字段为null IS NULL OR 字段为空='' SELECT * FROM 表名 WHERE LENGTH(字段)&g ...
- spring中使用i18n(国际化)
简单了解i18n i18n(其来源是英文单词internationalization的首末字符i和n,18为中间的字符数)是“国际化”的简称.在资讯领域,国际化(i18n)指让产品(出版物,软件,硬件 ...
- 【JS-Java-EL】JavaScript和Java(EL表达式)引发的 Uncaught SyntaxError: Unexpected token ILLEGAL
2018.10.14 BUG原因: 在较早期的代码中,容易出现 JS 拼接 HTML 代码字符串的情况.如 // 页面 test.jsp 内部的 JS 代码 // ${} JSP中EL语法,内部为Ja ...
- JS isArray、typeof、instanceof
Array.isArray() 用来检验是不是数组 var a = [1,2,3] console.log(typeof a); // object console.log(Array.isArray ...
- 在Linux文件清空的几种方法
在Linux文件清空的几种方法 1.使用重定向的方法 [root@centos7 ~]# du -h test.txt 4.0K test.txt [root@centos7 ~]# > tes ...