Description

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

Input

一个整数N

Output

如题

Sample Input

4

Sample Output

4

Hint

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

1<=N<=10^7

这个题目可以用欧拉函数或者莫比乌斯反演。

第一种欧拉函数:

因为gcd(x, y) = p,所以gcd(x/p, y/p) = 1。

不妨设y较大,那么就是求所有比y/p小的数k,phi(k)的和。phi(k)是欧拉函数,表示小于等于k,与k互质的数的个数。

然后每种乘2就得到了组数,但是需要减1,因为(1, 1)这组被计算了两次。

预处理所有phi(k)的前缀和就OK了,就能加速运算。

然后枚举质数p就OK了。

这个OJ我揣测是单组测试的,像下面预处理打表会T,需要对每个n进行一次打表。

代码:(欧拉函数)

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <algorithm>
#define LL long long using namespace std; const int maxN = 1e7+;
int n;
bool isprim[maxN];
int phi[maxN], prim[maxN], top;
LL s[maxN]; //埃氏筛法求素数
void isPrim()
{
top = ;
memset(isprim, true, sizeof(isprim));
isprim[] = isprim[] = false;//初始化
for (LL i = ; i < maxN; ++i)//筛法
{
if (isprim[i])
{
for (LL j = i*i; j < maxN; j += i)//上界太大可能会爆int
{
isprim[j] = false;
}
prim[top++] = i;
}
}
} //***筛法求欧拉函数
void phi_table()
{
memset(phi, , sizeof(phi));
phi[] = ;
s[] = ;
s[] = ;
for (int i = ; i < maxN; i++)
{
if (!phi[i])
for (LL j = i; j < maxN; j += i)//i如果太大可能会爆int
{
if (!phi[j])
phi[j] = j;
phi[j] = phi[j]/i*(i-);
}
s[i] = s[i-]+phi[i];
}
} void work()
{
LL ans = ;
for (int i = ; i < top && prim[i] <= n; ++i)
{
ans += *s[n/prim[i]];
ans--;
}
printf("%lld\n", ans);
} int main()
{
//freopen("test.in", "r", stdin);
isPrim();
phi_table();
while (scanf("%d", &n) != EOF)
{
work();
}
return ;
}

第二种莫比乌斯反演:

设F(d)表示d | gcd(x, y) (1 <= x <= N, 1 <= y <= M)

f(d)表示d = gcd(x, y) (1 <= x <= N, 1 <= y <= M)

那么自然F(d) = sum(f(n)) (d | n)

且F(d) = (N/d)*(M/d)

根据莫比乌斯反演:

F(d) = sum(f(n)) (d|n) => f(d) = sum(u(n/d)*F(n)) (d|n)

所以f(d) = f(d) = sum(u(n/d)*F(n)) (d|n)

然后d取遍质数

则ans = sum(f(p)) = sum( sum(u(n/p)*F(n)) (p|n) )

外层sum上界为min(M, N), 内层sum也为min(M, N)

这样复杂度是min(M^2, N^2)的,时间上过不去。

此外就是这两个sum的位置是可以替换的,

因为整个式子的结果就是所有p|n的情况都要加上,

原式是对于一个p把所有n的情况加起来,最后求和。

同样可以,对于每一个n把所有p的情况加起来,最后求和。

那么式子可以改写为:ans = sum( F(n)*sum(u(n/p)) ) (p|n)

这样,如果能在时限内预处理出每个n对应的sum(u(n/p)),那么就能在min(M, N)时间复杂度内求解。

这里可以先把所有sum初始化为0,然后类似于筛法的做法,对于一个p,把所有p的倍数n的sum,加上u(n/p)。

这样预处理的复杂度要nlogn左右。不过常数有点大,本地需要1S多才能跑出来。(网上有一种O(n)的做法)

同样的,下面的打表也会T,需要对每个n进行一次打表。

代码:(莫比乌斯)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <set>
#include <queue>
#include <vector>
#define LL long long using namespace std; const int maxN = 1e7+;
int u[maxN], cnt;
LL prime[maxN], sum[maxN];
bool vis[maxN]; void mobius()
{
memset(vis, false,sizeof(vis));
u[] = ;
cnt = ;
for(LL i = ; i < maxN; i++)
{
if(!vis[i])
{
prime[cnt++] = i;
u[i] = -;
}
for(int j = ; j < cnt && i*prime[j] < maxN; j++)
{
vis[i*prime[j]] = true;
if(i%prime[j])
u[i*prime[j]] = -u[i];
else
{
u[i*prime[j]] = ;
break;
}
}
}
} int n;
LL ans; void init()
{
mobius();
ans = ;
memset(sum, , sizeof(sum));
for (int i = ; i < cnt; ++i)
{
for (LL j = prime[i]; j < maxN; j += prime[i])
sum[j] += u[j/prime[i]];
}
} void work()
{
for (LL i = ; i <= n; ++i)
ans += (n/i)*(n/i)*sum[i];
printf("%lld\n", ans);
} int main()
{
//freopen("test.in", "r", stdin);
init();
while (scanf("%d", &n) != EOF)
work();
return ;
}
 

ACM学习历程—HYSBZ 2818 Gcd(欧拉函数 || 莫比乌斯反演)的更多相关文章

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

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

  2. BZOJ 2818: Gcd [欧拉函数 质数 线性筛]【学习笔记】

    2818: Gcd Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 4436  Solved: 1957[Submit][Status][Discuss ...

  3. BZOJ 2818 GCD 【欧拉函数 || 莫比乌斯反演】

    传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=2818 2818: Gcd Time Limit: 10 Sec  Memory Limit ...

  4. UVA11426 GCD - Extreme (II) (欧拉函数/莫比乌斯反演)

    UVA11426 GCD - Extreme (II) 题目描述 PDF 输入输出格式 输入格式: 输出格式: 输入输出样例 输入样例#1: 10 100 200000 0 输出样例#1: 67 13 ...

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

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

  6. 中国剩余定理 & 欧拉函数 & 莫比乌斯反演 & 狄利克雷卷积 & 杜教筛

    ssplaysecond的博客(请使用VPN访问): 中国剩余定理: https://ssplaysecond.blogspot.jp/2017/04/blog-post_6.html 欧拉函数: h ...

  7. BZOJ 2818 Gcd(欧拉函数+质数筛选)

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

  8. bzoj 2818 Gcd(欧拉函数 | 莫比乌斯反演)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2818 [题意] 问(x,y)为质数的有序点对的数目. [思路一] 定义f[i]表示i之 ...

  9. hdu6390 /// 欧拉函数+莫比乌斯反演 筛inv[] phi[] mu[]

    题目大意: 给定m n p 求下式   题解:https://blog.csdn.net/codeswarrior/article/details/81700226 莫比乌斯讲解:https://ww ...

随机推荐

  1. Python小白的发展之路之Python基础(二)【字符串、列表、集合、文件操作】

    列表.元组操作 字符串操作 字典操作 集合操作 文件操作 字符编码与转码 1.列表.元组操作 (1)列表 列表是可变的(mutable)——可以改变列表的内容,这不同于字符串和元组,字符串和元组都是不 ...

  2. 股神小L 2016Vijos省选集训 day1

    股神小L (stock.c/pas/cpp)============================ 小L厌倦了算法竞赛,希望到股市里一展身手.他凭借自己还行的计算机功底和可以的智商,成功建立一个模型 ...

  3. mysql存储过程之事务篇

    mysql存储过程之事务篇 事务的四大特征: ACID:Atomic(原子性).Consistent(一致性).Isolated(独立性).Durable (持久性) MySQL的事务支持不是绑定在M ...

  4. 软RAID5制作流程

    说明:本实验没有用到多个磁盘,而是利用单个磁盘划分出的多个分区来仿真的,如果在实际项目中,请依情况而定. 1. 分区 我这里划分6个分区,用4个分区组成RAID 5,用1个分区作为spare disk ...

  5. linux系统环境下搭建coreseek(+mmseg3) (good)

    1.下载并解压coreseek软件,操作命令如下: wget http://www.coreseek.cn/uploads/csft/3.2/coreseek-3.2.14.tar.gz 说明:文件下 ...

  6. python基础15 ---面像对象的程序设计

    面向对象的程序设计 一.面向对象的程序设计简介 1.面向对象程序设计的由来. 我们之前虽然学习过了面向过程的程序,它的核心是面向过程,一步一步的设计好了的流程,虽然极大的降低了程序的复杂度,但是一个设 ...

  7. 创建美国地区的appleId

      参考: https://zhuanlan.zhihu.com/p/36574047 美国人身份信息生成: https://www.fakeaddressgenerator.com/Index/in ...

  8. LeetCode:验证回文串【125】

    LeetCode:验证回文串[125] 题目描述 给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写. 说明:本题中,我们将空字符串定义为有效的回文串. 示例 1: 输入: ...

  9. Data Structure Array: Longest Monotonically Increasing Subsequence Size

    http://www.geeksforgeeks.org/longest-monotonically-increasing-subsequence-size-n-log-n/ #include < ...

  10. ios中文模糊搜索兼容问题

    $(function(){ var cpLock = true; $("input[name='name']").off().on({ compositionstart: func ...