博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[BZOJ 2818]Gcd
阅读量:5023 次
发布时间:2019-06-12

本文共 3380 字,大约阅读时间需要 11 分钟。

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

题解

由题,我们需要求

$$\sum_{i=1} ^N\sum_{j=1} ^N[gcd(i,j)为质数]$$

我们不妨令$p=gcd(i,j)$,即$p$为质数,

显然我们不可能去枚举每个$i$,$j$,我们考虑去枚举每个质数$p$,原式化为

$$\sum_p\sum_{i=1}^{\lfloor {N \over p} \rfloor}\sum_{j=1}^{\lfloor {N \over p} \rfloor}[gcd(i,j)=1]$$

我们取出数对$(i,j)$

1.若$i>j$,我们发现对于式子

$$\sum_p\sum_{i=1}^{\lfloor {N \over p} \rfloor}\sum_{j=1}^{\lfloor {N \over p} \rfloor}[gcd(i,j)=1]$$

可化为

$$\sum_p\sum_{i=1}^{\lfloor {N \over p} \rfloor}\sum_{j=1}^{i-1}[gcd(i,j)=1]$$

取出

$$\sum_{i=1}^{\lfloor {N \over p} \rfloor}\sum_{j=1}^{i-1}[gcd(i,j)=1]$$

发现,这其实就是欧拉函数$φ$的定义式(先不考虑$φ(1)=1$)。

那么原式就可以化为

$$\sum_p\sum_{i=1}^{\lfloor {N \over p} \rfloor}φ(i)$$

结论。

2.若$i=j$,这种条件下只有$i=j=p$符合条件,显然最后我们只要将答案加上素数的个数就可以了。

3.若$i<j$,实际上只要交换$i$,$j$位置即可,我们只需要将1.得出的结论$×2$即可。

1 #include 2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 #include
11 #include
12 #include
13 #include
14 #define LL long long15 #define RE register16 #define IL inline17 using namespace std;18 const int N=1e7;19 20 int n;21 22 bool isprime[N+5];23 int prime[N+5],top;24 int phi[N+5];25 IL void Pre();26 27 int main()28 {29 scanf("%d",&n);30 Pre();31 LL ans=0;32 for (RE int i=1;i<=top;i++)33 {34 int lim=n/prime[i];35 for (RE int j=1;j<=lim;j++) ans+=phi[j];36 }37 ans=ans*2+top;38 printf("%lld\n",ans);39 return 0;40 }41 42 IL void Pre()43 {44 for (RE int i=2;i<=n;i++)45 {46 if (!isprime[i]) phi[i]=i-1,prime[++top]=i;47 for (RE int j=1;j<=top&&i*prime[j]<=n;j++)48 {49 isprime[i*prime[j]]=1;50 if (!(i%prime[j])) {phi[i*prime[j]]=phi[i]*prime[j];break;}51 else phi[i*prime[j]]=phi[i]*phi[prime[j]];52 }53 }54 }

其实统计答案的第二层循环可以用前缀和优化。

1 //It is made by Awson on 2018.1.12 2 #include 
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 #include
11 #include
12 #include
13 #include
14 #include
15 #define LL long long16 #define Max(a, b) ((a) > (b) ? (a) : (b))17 #define Min(a, b) ((a) < (b) ? (a) : (b))18 #define Swap(a, b) ((a) ^= (b), (b) ^= (a), (a) ^= (b))19 using namespace std;20 const int N = 1e7;21 void read(int &x) {22 char ch; bool flag = 0;23 for (ch = getchar(); !isdigit(ch) && ((flag |= (ch == '-')) || 1); ch = getchar());24 for (x = 0; isdigit(ch); x = (x<<1)+(x<<3)+ch-48, ch = getchar());25 x *= 1-2*flag;26 }27 void write(LL x) {28 if (x > 9) write(x/10);29 putchar(x%10+48);30 }31 32 int n, isprime[N+5], prime[N+5], tot;33 LL phi[N+5], ans;34 35 void get_phi() {36 memset(isprime, 1, sizeof(isprime)); isprime[1] = 0;//, phi[1] = 1;37 for (int i = 2; i <= n; i++) {38 if (isprime[i]) phi[i] = i-1, prime[++tot] = i;39 for (int j = 1; j <= tot && i*prime[j] <= n; j++) {40 isprime[i*prime[j]] = 0;41 if (!(i%prime[j])) {phi[i*prime[j]] = phi[i]*prime[j]; break; }42 else phi[i*prime[j]] = phi[prime[j]]*phi[i];43 }44 }45 }46 void work() {47 read(n); get_phi();48 for (int i = 1; i <= n; i++) phi[i] += phi[i-1];49 for (int i = 1; i <= tot; i++) ans += phi[n/prime[i]];50 write(ans*2+tot);51 }52 int main() {53 work();54 return 0;55 }

 

转载于:https://www.cnblogs.com/NaVi-Awson/p/7294399.html

你可能感兴趣的文章
start
查看>>
实现手机扫描二维码页面登录,类似web微信-第三篇,手机客户端
查看>>
PHP socket客户端长连接
查看>>
7、shell函数
查看>>
【转】Apache Jmeter发送post请求
查看>>
Nginx 基本 安装..
查看>>
【凸优化】保留凸性的几个方式(交集、仿射变换、投影、线性分式变换)
查看>>
NYOJ-613//HDU-1176-免费馅饼,数字三角形的兄弟~~
查看>>
TFS --- GrantBackup Plan Permissions Error
查看>>
傅里叶级数与积分方程
查看>>
软工作业3:用户体验分析——以“南通大学教务管理系统微信公众号”为例
查看>>
Css:背景色透明,内容不透明之终极方法!兼容所有浏览器
查看>>
我们前端跟后端是怎么合作的
查看>>
mysql存储过程
查看>>
洛谷P2556 [AHOI2002] 黑白图像压缩 [模拟]
查看>>
letecode [136] - Single Number
查看>>
linux下设置固定IP的方法
查看>>
VMware虚拟机下Linux系统的全屏显示
查看>>
net core体系-web应用程序-4asp.net core2.0 项目实战(任务管理系统)-2项目搭建
查看>>
高效的jQuery
查看>>