YY的GCD

原题链接

这应该是我做的第一道莫比乌斯反演的题目。

题目描述

  • 神犇YY虐完数论后给傻×kAc出了一题
  • 给定N, M,求1<=x<=N, 1<=y<=M且gcd(x, y)为质数的(x, y)有多少对

    kAc这种傻×必然不会了,于是向你来请教……
  • 多组输入

输入输出格式

输入格式:

  • 第一行一个整数T 表述数据组数
  • 接下来T行,每行两个正整数,表示N, M

输出格式:

  • T行,每行一个整数表示第i组数据的结果

说明

  • T=10000,N, M <= 10000000

解题思路

  • 显然,题目要求的\(Ans\)实际上就是\(\sum_{i=1}^{n}\sum_{j=1}^{m}[gcd(x,y)=prim]\)的值
  • 接下来,我们就开始进行欢乐的推式子
  • 对于这种与\(gcd\)有关的莫比乌斯反演,一般我们都是套路的去设\(f(d)\)为\(gcd(i,j)=d\)的个数,\(F(n)\)为\(gcd(i,j)=n\)和\(n\)的倍数的个数,即:

\[f(d)=\sum_{i=1}^{n}\sum_{j=1}^{m}[gcd(i,j)=d]
\]

\[F(n)=\sum_{n|d}f(d)=\lfloor\frac{N}{n}\rfloor\lfloor\frac{M}{n}\rfloor
\]

\[f(n)=\sum_{n|d}\mu(\lfloor\frac{d}{n}\rfloor)F(d)
\]

  • 这样,我们便可以开心的化简这个式子了!

\[Ans=\sum_{p\in prim}\sum_{i=1}^{n}\sum_{j=1}^{m}[gcd(i,j)=p]
\]

将\(f(p)\)带入得:

\[Ans=\sum_{p\in prim}f(p)
\]

然后就莫比乌斯反演一下

\[Ans=\sum_{p\in prim}\sum_{p|d}\mu(\lfloor\frac{d}{p}\rfloor)F(d)
\]

我们换一个枚举项,我们枚举\(\lfloor\frac{d}{p}\rfloor\)

\[Ans=\sum_{p\in prim}\sum_{d=1}^{min(\lfloor\frac{n}{p}\rfloor,\lfloor\frac{m}{p}\rfloor)}\mu(d)F(dp)=\sum_{p\in prim}\sum_{d=1}^{min(\lfloor\frac{n}{p}\rfloor,\lfloor\frac{m}{p}\rfloor)}\mu(d)\lfloor\frac{n}{dp}\rfloor\lfloor\frac{m}{dp}\rfloor
\]

这个\(dp\)一看就很不爽,于是我们把它换成\(T\)

\[Ans=\sum_{T=1}^{min(n,m)}\sum_{t|T,t\in prime}\mu(\lfloor\frac{T}{t}\rfloor)\lfloor\frac{n}{T}\rfloor\lfloor\frac{m}{T}\rfloor
\]

\[Ans=\sum_{T=1}^{min(n,m)}\lfloor\frac{n}{T}\rfloor\lfloor\frac{m}{T}\rfloor(\sum_{t|T,t\in prime}\mu(\lfloor\frac{T}{t}\rfloor))
\]

  • 推到这里,我们就可以开始做了。如果是单组询问,我们就直接\(O(n)\)做。(不过好像一般这种题,都不会让你直接处理。)如果是多组数据的话,我们就只要在打一个简单的整除分块就可以了。后面的\(\mu\)函数可以线筛出来。由于整除分块的缘故,我们就只需要记一个前缀和就可以了。
  • 下面贴一个完整的代码吧。
#include<bits/stdc++.h>
#define N 10000100
using namespace std;
inline void read(int &x)
{
x=0;
static int p;p=1;
static char c;c=getchar();
while(!isdigit(c)){if(c=='-')p=-1;c=getchar();}
while(isdigit(c)) {x=(x<<1)+(x<<3)+(c-48);c=getchar();}
x*=p;
}
inline void print(long long x)
{
static int cnt;
static int a[15];
cnt=0;
do
{
a[++cnt]=x%10;
x/=10;
}while(x);
for(int i=cnt;i>=1;i--)putchar(a[i]+'0');
puts("");
}
bool vis[N];
long long sum[N];
int prim[N];
int mu[N],g[N];
int cnt;
void get_mu(int n)
{
mu[1]=1;
for(int i=2;i<=n;i++)
{
if(!vis[i]){mu[i]=-1;prim[++cnt]=i;}
for(int j=1;j<=cnt&&prim[j]*i<=n;j++)
{
vis[i*prim[j]]=1;
if(i%prim[j]==0)break;
else mu[prim[j]*i]=-mu[i];
}
}
for(int j=1;j<=cnt;j++)
for(int i=1;i*prim[j]<=n;i++)g[i*prim[j]]+=mu[i];
for(int i=1;i<=n;i++)sum[i]=sum[i-1]+(long long)g[i];
}
int n,m;
int main()
{
#ifndef ONLINE_JUDGE
freopen("P2257.in","r",stdin);
freopen("P2257.out","w",stdout);
#endif
int t;
read(t);
get_mu(10000000);
while(t--)
{
read(n);read(m);
if(n>m)swap(n,m);
static long long ans;ans=0;
for(int l=1,r;l<=n;l=r+1)
{
r=min(n/(n/l),m/(m/l));
ans+=1ll*(n/l)*(m/l)*(sum[r]-sum[l-1]);
}
print(ans);
}
return 0;
}

洛谷【P2257】YY的GCD的更多相关文章

  1. 洛谷 P2257 YY的GCD

    洛谷 P2257 YY的GCD \(solution:\) 这道题完全跟[POI2007]ZAP-Queries (莫比乌斯反演+整除分块) 用的一个套路. 我们可以列出答案就是要我们求: \(ans ...

  2. 洛谷 - P2257 - YY的GCD - 莫比乌斯反演 - 整除分块

    https://www.luogu.org/problemnew/show/P2257 求 \(n,m\) 中 \(gcd(i,j)==p\) 的数对的个数 求 $\sum\limits_p \sum ...

  3. 洛谷 P2257 YY的GCD 题解

    原题链接 庆祝: 数论紫题 \(T4\) 达成! 莫比乌斯 \(T1\) 达成! yy 真是个 神犇 前记 之前我觉得: 推式子,直接欧拉筛,筛出个 \(\phi\),然后乱推 \(\gcd\) 就行 ...

  4. 洛谷 P2257 - YY的GCD(莫比乌斯反演+整除分块)

    题面传送门 题意: 求满足 \(1 \leq x \leq n\),\(1 \leq y \leq m\),\(\gcd(x,y)\) 为质数的数对 \((x,y)\) 的个数. \(T\) 组询问. ...

  5. 洛谷P2257 YY的GCD 莫比乌斯反演

    原题链接 差不多算自己推出来的第一道题QwQ 题目大意 \(T\)组询问,每次问你\(1\leqslant x\leqslant N\),\(1\leqslant y\leqslant M\)中有多少 ...

  6. 洛谷P2257 YY的GCD

    今日份是数论 大概是..从小学奥数到渐渐毒瘤 那就简单列一下目录[大雾 同余 质数密度 唯一分解定理 互质 完全剩余系 简化剩余系 欧拉函数 逆元 斐蜀定理 阶(及其性质) 欧拉定理 费马小定理 原根 ...

  7. 洛谷P2257 YY的GCD(莫比乌斯反演)

    传送门 原来……莫比乌斯反演是这么用的啊……(虽然仍然不是很明白) 首先,题目所求如下$$\sum_{i=1}^n\sum_{j=1}^m[gcd(i,j)=prim]$$ 我们设$f(d)$表示$g ...

  8. 解题:洛谷2257 YY的GCD

    题面 初见莫比乌斯反演 有一个套路是关于GCD的反演经常设$f(d)=\sum_{gcd(i,j)==d},g(d)=\sum_{d|gcd(i,j)}$,然后推推推 $\sum\limits_{i= ...

  9. [洛谷2257]YY的GCD 题解

    整理题目转化为数学语言 题目要我们求: \[\sum_{i=1}^n\sum_{i=1}^m[gcd(i,j)=p]\] 其中 \[p\in\text{质数集合}\] 这样表示显然不是很好,所以我们需 ...

  10. 洛谷 2257 - YY的GCD

    莫比乌斯反演半模板题 很容易可以得到 \[Ans = \sum\limits_{p \in prime} \sum\limits_{d = 1}^{\min (\left\lfloor\frac{a} ...

随机推荐

  1. Jmeter操作之跨线程组传递参数

    思路:将某一线程组内的变量通过“__setProperty”函数设置成jmeter的全局变量,在另一线程组中通过“__P”函数调用即可. 1.添加-后置处理器-BeanShell PostProces ...

  2. Servlet 使用ServletContext共享数据,读取web.xml配置

    ServletContext对象 session和cookie,对于每一个请求用户来说,都是不同的,因为要保证隐私安全. 而有一些数据,可以让所有用户共享,此时就可以用ServletContext对象 ...

  3. 利用php查看某个服务的进程数

    查看进程就是使用ps命令而已,只不顾ps的参数太多了. 使用php查询的话,必须要开启几个函数(可以执行外部程序的函数),参考官网:http://php.net/manual/zh/book.exec ...

  4. Docker Compose vs. Dockerfile

    Docker Compose vs. Dockerfile - which is better? - Stack Overflowhttps://stackoverflow.com/questions ...

  5. C\C++学习笔记 1

    C++记录1 C的头文件为math.h C++的为 cmath using编译指令 namespace 区分不同产品的函数.Mics::cout Linux::cout cout << 即 ...

  6. Day5-1 面向对象和面向过程

    摘要: 类的定义 类的增删改查 对象的增删改查 对象的查找和绑定 面向对象和面向过程的区别: 1.面向过程就像是工厂的流水线,按部就班的有序的工作. 优点:把复杂的问题简单化 缺点:可扩展性差.一个步 ...

  7. Bootstrap 面板(Panels)

    一.面板组件用于把 DOM 组件插入到一个盒子中.创建一个基本的面板,只需要向 <div> 元素添加 class .panel 和 class .panel-default 即可,如下面的 ...

  8. java中级——集合框架【1】-ArrayList

    集合框架----ArrayList 引子:我们先来看看传统数组的用法 写一个Hero对象类 package cn.jse.t1; public class Hero { public String n ...

  9. drf信号量

    Django信号量回顾及drf信号量常用操作 一.在写接口视图时,保存/删除/更新数据前后需要对序列化后的数据进行处理的方法: 1.重写mixins.CreateModelMixin中恩的create ...

  10. mysql高可用架构之MHA,haproxy实现读写分离详解

    MySQL高可用架构之MHA 一.运维人员需要掌握的MySQL技术: 1.基本SQL语句 2.基本的管理[库表数据的管理    权限的管理] 3.容灾       保证数据不丢失. 二.工作中MySQ ...