[BZOJ2818]Gcd
2015-08-05 22:21
190 查看
原题地址
题目大意:给定整数N,求x,y∈[1,N]且gcd(x,y)为素数的数对(x,y)有多少对(N≤107).
做法:用筛法Θ(n)求出素数表和欧拉函数表以后,一切都变得很简单了,所以主要讲一下筛法.
Θ(n)素数筛原理:对于一个合数n,总能唯一表示成n=p×m的形式,其中p是n的最小质因子.
Θ(n)筛法求欧拉函数的原理:对于一个合数n,ϕ(n)总能唯一表示成ϕ(p×m)的形式,其中p是n的最小质因子.
然后根据欧拉函数性质:
然后就可以同时求质数表和欧拉函数了,具体见下面代码.
AC code:
题目大意:给定整数N,求x,y∈[1,N]且gcd(x,y)为素数的数对(x,y)有多少对(N≤107).
做法:用筛法Θ(n)求出素数表和欧拉函数表以后,一切都变得很简单了,所以主要讲一下筛法.
Θ(n)素数筛原理:对于一个合数n,总能唯一表示成n=p×m的形式,其中p是n的最小质因子.
Θ(n)筛法求欧拉函数的原理:对于一个合数n,ϕ(n)总能唯一表示成ϕ(p×m)的形式,其中p是n的最小质因子.
然后根据欧拉函数性质:
ϕ(n)={ϕ(np)×p (npmod p=0)ϕ(np)×(p−1) (npmod p≠0)
为什么?你想一下通式…然后就可以同时求质数表和欧拉函数了,具体见下面代码.
AC code:
#include <cstdio> typedef long long ll; const int N=10000010; int n,tot; int prime ,phi ; bool flag ; ll ans; ll S ; int main(){ scanf("%d",&n); phi[1]=S[1]=1; for(int i=2;i<=n;i++){ if(!flag[i]){ prime[++tot]=i; phi[i]=i-1; } for(int j=1;j<=tot&&i*prime[j]<=n;j++){ flag[i*prime[j]]=1; if(i%prime[j]) phi[i*prime[j]]=phi[i]*(prime[j]-1); else{ phi[i*prime[j]]=phi[i]*prime[j]; break; } } } for(int i=2;i<=n;i++) S[i]=S[i-1]+(phi[i]<<1); for(int i=1;i<=tot;i++) ans+=S[n/prime[i]]; printf("%lld\n",ans); return 0; }
相关文章推荐
- Oracle 游标使用全解
- 黑马程序员——struts2学习笔记二(结果类型)
- UIScrollview
- JavaScript-基本语法和数据类型
- hdoj1045
- Android 非空格式验证框架的使用,验证邮箱,非空,2选1等等
- 【USACO OPEN 10】hop
- Construct Binary Tree from Preorder and Inorder Traversal
- 怎样数出有多少个三角形?
- C/C++学习之构造函数
- MCU低功耗设计(二)实践
- jsoup抓取网页+详细讲解
- 爆栈解决方法
- poj2421kruskal算法模板题
- Binary Tree Preorder Traversal
- 给出现el表达式异常,但自我检查没有发现任何问题的朋友的忠告
- javascript高级编程技术 第三章
- yii中事件的了解
- day05_数组_冒泡排序_Arrays_20150805
- Median of Two Sorted Arrays