题目

题目描述

给定整数$N$,求$1 \le x,y \le N$且$gcd(x,y)\(为素数的数对\)(x,y)$有多少对。

$gcd(x,y)$即求$x,y$的最大公约数。

输入格式

输入一个整数N

输出格式

输出一个整数,表示满足条件的数对数量。

数据范围

\[
1 \le N \le 10^7
\]

输入样例:

4

输出样例:

4

解题报告

关于本题

这道题目,在蒟蒻我花费了30min一顿瞎搞AC后,然后想要看网络上的题解,都是一些什么莫比乌斯反演,吓了一跳.

原题:最大公约数

大佬团:这道题目当然要莫比乌斯反演性质推导啊,这样时间效率特别高.

蒟蒻我:我只用了一个欧拉函数+前缀和瞎搞.

然后蒟蒻我想要感受一下,传说中的省选高端数学算法,莫比乌斯反演的效率.

于是我测试了一下代码.

莫比乌斯反演算法,花费4000+ms.

欧拉函数算法,花费933ms.

蒟蒻我,一脸懵逼.

后来我又搜索了这道题目的另外一个100%相似版本,终于看到了类似的算法,但是为什么处理方式那么诡异啊,网上都是$ans \times 2-1$,我是$ans \times 2+1$

可能我的打开方式不对吧............


题意理解

就是要找统计一类特殊数对.

要求两个数,他们的最大公约数为素数.


算法解析

这道题目思路比较清晰,除了算法基础课上的欧拉函数,完全没有高级数学知识,只有最大公约数,乘法这些数学知识,而且公式都非常简短,可以放心食用.违背了数学题目的常识

我们先来下定义.

\[
a=x \times d \quad x为任意正整数\\\\
b=y \times d \quad y为任意正整数\\\\
d为素数 \\\\
\]

那么什么时候才会出现

\[
gcd(a,b)=d
\]

也就是题目要求统计的数对呢?

我们思索一下,什么是最大公约数,不就是两个数的最大公因子吗?

那么我们把定义放入进去.

\[
a=x \times d \\\\
b=y \times d \\\
gcd(a,b)=gcd(x \times d,y \times d)=d \\\\
gcd(a,b)=d \times gcd(x,y)
\]

此时我们应该很好看出来了,一个$a,b$为合法数对的条件了.

\[
gcd(x,y)=1 \quad x,y必须互素
\]

否则的话,我们观察发现

\[
gcd(a,b)=d \times gcd(x,y) \\\\
如果不满足gcd(x,y)=1的话 \\\\
d \times gcd(x,y) \not= d \\\\
\]

一个素数乘以一个大于1的数字,请问还有可能是素数吗?

显然是不可能的.

所以我们就证明了这个性质.

既然如此的话,我们发现了性质,那么就要推导公式了.

对于一个素数$d$而言.他在$1$~$n$中显然有这些数.

\[
d,d \times 2,d \times 3,...,d \times k. \\\\
d \times k \le n
\]

我们发现$gcd(a,b)=d$的数对,只能从上面这个式子中选择.

因为最大公约数是$d$,所以必须有共同因子\(d\).

那么我们再来简化数列,也就是上面式子,都抛去d.

\[
a/=d \\\\
b/=d.
\]

那么$a,b$就会从下面这个数列中选择

\[
1,2,3,...k
\]

我们再来分析.

因为合法数对$a,b$都除以$d$这个最大公约数,所以此时.

\[
gcd(a,b)=d \\\
==> gcd(a/d,b/d)=1
\]

总而言之,言而总之,我们要

在下面这个数列中,找到两个互质的数,那么一定是合法数对.

\[
1,2,3,...k
\]

比如说我们选择

\[
2,3
\]

那么实际上对应的数字就是

\[
2\times d,3\times d
\]

因此当前的任务就是找到互质的两个数.

此时我们就需要用到这道题目唯一的难点数学知识.

欧拉函数:是小于n的正整数中与n互质的数的数目

那么我们对于一个数列而言,它的欧拉函数总和,就是两个互质数对个数.

\[
ans=\phi{1} + \phi{2} + \phi{3} +...+\phi{k}
\]

不过本题目是无序数对,因此.

\[
ans \times 2
\]

因此使用线性筛法,就可以$O(n)\(求出每一个\)\phi$

不过为了加速处理,我们还可以使用前缀和数组.

\[
sum[i]表示 \phi{1}+\phi{2}+\phi{3}+..+\phi{k}的总和
\]

代码解析

//代码是单数据版本的
#include <bits/stdc++.h>
const int N=1e7+10;
using namespace std;
int zs[N],cnt,phi[N],n;
long long sum[N],ans;
bool st[N];
void get_phi(int n)
{
phi[1]=1;
for (int i=2; i<=n; i++)
{
if (!st[i])
{
zs[cnt++]=i;
phi[i]=i-1;
}
for (int j=0; zs[j]<=n/i; j++)
{
int t=zs[j]*i;
st[t]=true;
if (i%zs[j]==0)
{
phi[t]=phi[i]*zs[j];
break;
}
phi[t]=phi[i]*(zs[j]-1);
}
}
}
int main()
{
scanf("%d",&n);
get_phi(n);
for(int i=2;i<=n;i++)
sum[i]=sum[i-1]+phi[i];
for(int i=0;i<cnt;i++)
{
int now=n/zs[i];
ans+=sum[now]*2+1;//因为phi[1]=1,我们的前缀和没有处理.
}
printf("%lld\n",ans);
return 0;
}

BZOJ 最大公约数 (通俗易懂&效率高&欧拉函数)的更多相关文章

  1. BZOJ 2705: [SDOI2012]Longge的问题 [欧拉函数]

    2705: [SDOI2012]Longge的问题 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 2553  Solved: 1565[Submit][ ...

  2. Bzoj 2705: [SDOI2012]Longge的问题 欧拉函数,数论

    2705: [SDOI2012]Longge的问题 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 1959  Solved: 1229[Submit][ ...

  3. BZOJ 3813--奇数国(线段树&欧拉函数&乘法逆元&状态压缩)

    3813: 奇数国 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 755  Solved: 432[Submit][Status][Discuss] ...

  4. 【洛谷 P1390】 公约数的和 (欧拉函数)

    题目链接 做过\(n\)遍这种题了... 答案就是\(\sum_{i=1}^{n}\sum_{j=1}^{n/i}[\varphi(j)*i]\) 线筛欧拉函数求前缀和直接算就行. #include ...

  5. 51nod 1237 最大公约数之和 V3【欧拉函数||莫比乌斯反演+杜教筛】

    用mu写lcm那道卡常卡成狗(然而最后也没卡过去,于是写一下gcd冷静一下 首先推一下式子 \[ \sum_{i=1}^{n}\sum_{j=1}^{n}gcd(i,j) \] \[ \sum_{i= ...

  6. BZOJ 2818 Gcd (莫比乌斯反演 或 欧拉函数)

    2818: Gcd Time Limit: 10 Sec  Memory Limit: 256 MB Submit: 2534  Solved: 1129 [Submit][Status][Discu ...

  7. 【BZOJ】2190 [SDOI2008]仪仗队(欧拉函数)

    Description 作为体育委员,C君负责这次运动会仪仗队的训练.仪仗队是由学生组成的N * N的方阵,为了保证队伍在行进中整齐划一,C君会跟在仪仗队的左后方,根据其视线所及的学生人数来判断队伍是 ...

  8. BZOJ 2190:[SDOI2008]仪仗队(欧拉函数)

    [SDOI2008]仪仗队 Description 作为体育委员,C君负责这次运动会仪仗队的训练.仪仗队是由学生组成的N * N的方阵,为了保证队伍在行进中整齐划一,C君会跟在仪仗队的左后方,根据其视 ...

  9. [bzoj 1409] Password 矩阵快速幂+欧拉函数

    考试的时候想到了矩阵快速幂+快速幂,但是忘(bu)了(hui)欧拉定理. 然后gg了35分. 题目显而易见,让求一个数的幂,幂是斐波那契数列里的一项,考虑到斐波那契也很大,所以我们就需要欧拉定理了 p ...

随机推荐

  1. Leetcode之动态规划(DP)专题-486. 预测赢家(Predict the Winner)

    Leetcode之动态规划(DP)专题-486. 预测赢家(Predict the Winner) 给定一个表示分数的非负整数数组. 玩家1从数组任意一端拿取一个分数,随后玩家2继续从剩余数组任意一端 ...

  2. 【转帖】安卓的Bionic 简介

    https://blog.csdn.net/yongyu_it/article/details/52574797 google 自己实现了一套libc 的库函数 比glibc 要小一些 占用内存也小. ...

  3. win10下访问vm虚拟机Linux服务

    一.环境 win10操作系统 centos6.5 VMware® Workstation 14 Pro虚拟机 二.互相访问设置步骤 1.查看如下图所示 2.记住上面的IP和网关,进行如下图操作 点击应 ...

  4. redis 发布订阅、geo、bitmap、hyperloglog

    1.发布订阅 简介 发布订阅类似于广播功能.redis发布订阅包括 发布者.订阅者.Channel 命令 命令 作用 时间复杂度 subscribe channel 订阅一个频道 O(n) unsub ...

  5. 区间DP(入门)括号匹配

    https://www.nitacm.com/problem_show.php?pid=8314 思路:类似于https://blog.csdn.net/MIKASA3/article/details ...

  6. Feign的雪崩处理

    在声明式远程服务调用Feign中,实现服务灾难性雪崩效应处理也是通过Hystrix实现的.而feign启动器spring-cloud-starter-feign中是包含Hystrix相关依赖的.如果只 ...

  7. Java回调实现异步 (转)

    出处: Java回调实现异步 在正常的业务中使用同步线程,如果服务器每处理一个请求,就创建一个线程的话,会对服务器的资源造成浪费.因为这些线程可能会浪费时间在等待网络传输,等待数据库连接等其他事情上, ...

  8. css多种方式实现等宽布局

    本文讲的等宽布局是在不手动设置元素宽度的情况下,使用纯css实现各个元素宽度都相当的效果. 1.使用table-cell实现(兼容ie8) <style> body,div{ margin ...

  9. T100——作业action执行其他P作业,后台背景执行完后才能继续操作改作业

    范例:如axmt500订单,查询开单占用量: 客制作业cxmp500,通过参数-订单号,查询该订单下的料件,目前有库存量.开单占用量.库存可用量,查询后更新到该订单下的单身对应栏位: 现在axmt50 ...

  10. Linux中设置系统时间和时区

    之前公司里有需求要做机器与服务器做时间同步,服务器发送时间戳和时区过来,机器这边根据接收到的时间戳和时区来改时间. 其实很简单,百度上应该也有很多博客有类似的教程,但是这里强调一点,百度上的博客里写的 ...