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. 【BZOJ2844】albus就是要第一个出场 高斯消元求线性基

    [BZOJ2844]albus就是要第一个出场 Description 已知一个长度为n的正整数序列A(下标从1开始), 令 S = { x | 1 <= x <= n }, S 的幂集2 ...

  2. CSS 布局实例系列(二)如何通过 CSS 实现一个左边固定宽度、右边自适应的两列布局

    最近在百度 IFE 训练营中看见的一道题目: 用两种不同的方法来实现一个两列布局,其中左侧部分宽度固定.右侧部分宽度随浏览器宽度的变化而自适应变化  个人总结出如下三种实现思路: 通过绝对定位实现 S ...

  3. FTP开启被动连接模式

    在Linux环境下搭建ftp服务器,具体步骤见:http://www.cnblogs.com/zjiacun/p/6896803.html 配置被动连接的方法: 找到配置文件/etc/vsftpd/v ...

  4. SAP basis 常用事物

    1.创建一个新的用户 完成client创建和拷贝后,在开始正式工作之前,需要创建新的用户.  用这个用户进行工作.默认ddic和sap*用户不要用于实际的业务.  创建用户的过程很简单,只要以su01 ...

  5. 3.16课·········C#小结

    //附加//C#源码,被C#编译器,编译成执念代码(IL)//int16=short.....±32000//int32=int.......±21亿//int64=long......±922亿亿3 ...

  6. 2018年长沙理工大学第十三届程序设计竞赛 G 逃离迷宫 【BFS】

    链接:https://www.nowcoder.com/acm/contest/96/G 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言65536 ...

  7. Data Structure Binary Tree: Print ancestors of a given binary tree node without recursion

    http://www.geeksforgeeks.org/print-ancestors-of-a-given-binary-tree-node-without-recursion/ #include ...

  8. Data Structure Binary Tree: Convert a given Binary Tree to Doubly Linked List

    http://www.geeksforgeeks.org/in-place-convert-a-given-binary-tree-to-doubly-linked-list/ #include &l ...

  9. linux通过脚本获取内存信息

    1 原理 脚本中通过执行free获取内存信息,然后将文本信息通过“空格”分隔符分割成字符串数组将不同信息提取出来,最后通过bc计算出百分比 2 脚本 #!/bin/shHOSTNAME=`hostna ...

  10. 爬虫 spider

    python 2.x # -*- coding: utf-8 -*-import reimport urllib url = 'http://tieba.baidu.com/p/4872795764' ...