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. [Matlab绘图][三维图形][三维曲线基本函数+三维曲面+其他三维图形]

    1.绘制三维图形的基本函数 最基本的三维绘图函数为plot3: plot3与plot用法十分相似,调用格式: plot(x1,y1,z1,选项1,x2,y2,z2,选项2,...,xn,yn,zn,选 ...

  2. AFN errorCode对应的状态码

    转 http://blog.csdn.NET/wangyanchang21/article/details/50932191 在很多时候都会遇到错误, 还会带有一些 Error Code , 比如在各 ...

  3. Frobenius Norm

    http://mathworld.wolfram.com/FrobeniusNorm.html

  4. Centos 6 安装 python2.7 和 pip

    一.安装 python2.7 [root@crazy-acong ~]# cd /data/tools/ [root@crazy-acong tools]# yum groupinstall &quo ...

  5. 超轻量级、高性能C日志库--EasyLogger

    [ 声明:版权全部,欢迎转载.请勿用于商业用途. 联系信箱:armink.ztl@gmail.com] EasyLogger 1. 介绍 EasyLogger 是一款超轻量级(ROM<1.6K, ...

  6. Linux软件包分类

    源代码包 优点: 1.给你的就是源代码 2.可以修改源代码 3.可以自由选择所需的功能 4.软件是在自己电脑上编译安装,所以更加稳定高效 5.卸载方便(直接删了你安装软件的那个目录就好了) 缺点: 1 ...

  7. (转)ubuntu 12.04搭建Adobe Flash Media Server服务

    破解版传送门:http://fms45.cuplayer.com/fms4download.html 福利:1462-5247-1705-7678-8379-5590 下载解压 cd进目录,./ins ...

  8. python实例1:创建一个登陆模块

    实现功能: 1.用户输入账户密码 2.验证账户是否存在于黑名单,如果存在于黑名单,则执行1,否则往下执行 3.验证用户名和密码. 3.1.如果验证成功,则打印欢迎信息并退出程序: 3.2.如果用户名存 ...

  9. (转)Spring 缓存EhCacheFactoryBean

    Spring使用Cache 从3.1开始,Spring引入了对Cache的支持.其使用方法和原理都类似于Spring对事务管理的支持.Spring Cache是作用在方法上的,其核心思想是这样的:当我 ...

  10. HDU - 1033 Edge 【模拟】

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1033 题意 给定一个起始点 300 420 走的第一步是 310 420 下面的每一步 都由 输入决定 ...