题目描述

给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的数对(x,y)有多少对.

输入格式

一个整数N

输出格式

答案

输入输出样例

输入 #1

4

输出 #1

4

说明/提示

对于样例(2,2),(2,4),(3,3),(4,2)

1<=N<=10^7



由题意得:gcd(x,y)=p(这里我们假设p为一个已知的质数),并且下面的过程都在这个条件下进行,我们不妨设x<=y<=n。

令x=a*p,y=b*p,则有gcd(a,b)=1,且1<=a,b<=n/p。同样不妨设a<=b(☚什么情况下会等于后面有讲到)。

那么满足gcd(x,y)=p的数对(x,y)个数其实就是满足gcd(a,b)=1的数对个数(a,b)。(下面用num(x,y)来表示满足gcd(x,y)=p的数对(x,y)个数,num(a,b)同理)

对于b来说,b的取值范围是1~n/p,而a的取值可以是φ(b)中的任意一个,所以num(x,y)=num(a,b)=∑φ(b)(b∈[1,n/p]),简单来说,就是1~n/p中所有数的欧拉函数值的和


好,代码已经成功一大半了,但是现在我们并没有p的准确值,p可能是1~n中的任意一个质数。所以我们可以在预处理中先把1~n中的质数(p1、p2……)全部找出来,最后一一枚举这些质数,每枚举一个p,就处理 当gcd(x,y)等于此时的p 的时候的num(x,y),加到最后输出的结果ans中

代码实现:首先,我们用线性筛法求出1~n中每个数的欧拉函数值,用一个数组sum(注意要开long long)来存欧拉函数值的前缀和,方便后面查找值。

其实可以这样理解,sum[i]存的就是1~i中所有数的欧拉函数值的和,也就是上面讲到的num(x,y)

那么最后枚举1~n中的质数,每一次循环都得到了一个n/p值,即b的上界,那么此时的sum[n/p]*2-1就是满足gcd(x,y)=p的(x,y)的对数。

解释一下:由样例可得,(2,4)和(4,2)是不同的两种答案,所以x,y可以交换位置得到一个新的答案,所以sum[n/p]要*2,;但是当a=b=1,即x=y=p时,只有一种答案,所以sum[n/p]*2需要再-1,将重复的删去。

 #include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=;
int n;
ll sum[N],vis[N],p[N],phi[N];
int main()
{
scanf("%d",&n);
memset(vis,,sizeof(vis));
vis[]=vis[]=false;
phi[]=;
for(int i=;i<=n;i++)
{
if(vis[i])p[++p[]]=i,phi[i]=i-;//记得找出质数
for(int j=;j<=p[]&&p[j]*i<=n;j++)
{
vis[p[j]*i]=false;
if(i%p[j])phi[i*p[j]]=phi[p[j]]*phi[i];
else
{
phi[i*p[j]]=p[j]*phi[i];
break;
}
}//线性筛法
}
for(int i=;i<=n;i++)sum[i]=sum[i-]+phi[i];//前缀和
ll ans=;
for(int i=;i<=p[]&&p[i]<=n;i++)//枚举1~n中的所有质数
ans+=(sum[n/p[i]]<<)-;//sum[n/p]*2-1
printf("%lld",ans);
return ;
}

写这篇题解的时候思维比较混乱,我都不知道该如何组织语言了,花了超长时间的!希望能让你理解吧OvO

如果可以的话,给个“推荐”资瓷一下吧(*^▽^*)

//参考:zhou_yk 的博客

GCD(洛谷 2568)的更多相关文章

  1. 洛谷 P1890 gcd区间

    P1890 gcd区间 题目提供者 洛谷OnlineJudge 标签 数论(数学相关) 难度 普及/提高- 题目描述 给定一行n个正整数a[1]..a[n]. m次询问,每次询问给定一个区间[L,R] ...

  2. 洛谷 P2257 YY的GCD

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

  3. 洛谷P2568 GCD(线性筛法)

    题目链接:传送门 题目: 题目描述 给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的数对(x,y)有多少对. 输入输出格式 输入格式: 一个整数N 输出格式: 答案 输入输出样例 ...

  4. 洛谷P2398 GCD SUM (数学)

    洛谷P2398 GCD SUM 题目描述 for i=1 to n for j=1 to n sum+=gcd(i,j) 给出n求sum. gcd(x,y)表示x,y的最大公约数. 输入输出格式 输入 ...

  5. [洛谷P1029]最大公约数与最小公倍数问题 题解(辗转相除法求GCD)

    [洛谷P1029]最大公约数与最小公倍数问题 Description 输入二个正整数x0,y0(2<=x0<100000,2<=y0<=1000000),求出满足下列条件的P, ...

  6. 【题解】洛谷P1072 Hankson的趣味题 (gcd和lcm的应用)

    洛谷P1072:https://www.luogu.org/problemnew/show/P1072 思路 gcd(x,a0)=a1 lcm(x,b0)=b1→b0*x=b1*gcd(x,b0) ( ...

  7. 洛谷P2568 GCD (欧拉函数/莫比乌斯反演)

    P2568 GCD 题目描述 给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的数对(x,y)有多少对. 输入输出格式 输入格式: 一个整数N 输出格式: 答案 输入输出样例 输入 ...

  8. 【洛谷2257/BZOJ2820】YY的GCD(数论/莫比乌斯函数)

    题目: 洛谷2257 预备知识:莫比乌斯定理(懵逼乌斯定理) \(\mu*1=\epsilon\)(证bu明hui略zheng) 其中(我校学长把\(\epsilon(x)\)叫单位函数但是为什么我没 ...

  9. 洛谷 P5502 - [JSOI2015]最大公约数(区间 gcd 的性质+分治)

    洛谷题面传送门 学校模拟赛的某道题让我联想到了这道题-- 先讲一下我的野鸡做法. 首先考虑分治,对于左右端点都在 \([L,R]\) 中的区间我们将其分成三类:完全包含于 \([L,mid]\) 的区 ...

随机推荐

  1. 集合类源码(二)Collection之List(ArrayList, LinkedList, Vector)

    ArrayList 功能 完全命名 public class ArrayList<E> extends AbstractList<E> implements List<E ...

  2. [转帖]k8s 如何让你的应用活的更久

    k8s 如何让你的应用活的更久 https://www.jianshu.com/p/132319e795ae 众所周知,k8s 可以托管你的服务 / 应用,当出现各种原因导致你的应用挂掉之后,k8s ...

  3. 02、策略模式(Strategy)

    一.概念: 策略是为达到某一目的而采取的手段或方法,策略模式的本质是目标与手段的分离, 手段不同而最终达成的目标一致.客户只关心目标而不在意具体的实现方法, 实现方法要根据具体的环境因素而变化. 二. ...

  4. Linux(01):linux的起源、应用场景和学习目标

  5. WPF 精修篇 WPF嵌入Winfrom控件

    原文:WPF 精修篇 WPF嵌入Winfrom控件 先增加DLL 支持 使用  WindowsFormsHost 来加载Forms的控件 引用命名空间 xmlns:forms="clr-na ...

  6. ElasticSearch查看删除关闭索引

    curl -XDELETE 'http://10.1.2.2:9200/iis_log_2019-07'     #删除名为/iis_log_2019-07的索引 curl -XPOST 'http: ...

  7. 构造命题公式的真值表--biaobiao88

    对给出的任意一个命题公式(不超过四个命题变元),使学生会用C语言的程序编程表示出来,并且能够计算它在各组真值指派下所应有的真值,画出其真值表. #include<iostream> usi ...

  8. 2019 浩德钢圈java面试笔试题 (含面试题解析)

      本人5年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.浩德钢圈等公司offer,岗位是Java后端开发,因为发展原因最终选择去了浩德钢圈,入职一年时间了,也成为了面 ...

  9. English--元音

    English|元音 在一开始学习英语的时候,最需要掌握的就是音标.所以需要从音标的元音开始,并且不局限于掌握音标的元音与辅音,大家可以参考下英文版发音课,并不知道只学习元音与辅音,还有各种弱读连读等 ...

  10. js中数组的迭代方法

    1.forEach 让数组的每一项做一件事 var arr = [1,2,3,4,5] arr.forEach(function(item,index){ console.log(item) }) 2 ...