BZOJ-2818-Gcd(欧拉函数/Mobius反演)
2016-05-06 19:28
477 查看
Description
给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的数对(x,y)有多少对.
Input
一个整数NOutput
如题Sample Input
4Sample Output
4HINT
hint对于样例(2,2),(2,4),(3,3),(4,2)
1<=N<=10^7
首先欧拉函数:
小推一下公式:
Ans=prime(p)sigma(n,x=1)sigma(n,y=1)gcd(x,y)=p
=prime(p)sigma(n/p,x=1)sigma(n/p,y=1)gcd(x,y)=1
显然,预先累加处理一下欧拉函数phi[i]表示i内(x,y)互质对数,然后枚举n的质因子p,累加就可以了,
但是注意此题答案无序,而预先处理出的是有序的,所以需要乘2再减掉重复的形如(3,3)的就好。
#include <bits/stdc++.h> #define INF 0x3f3f3f3f #define LL long long #define bug cout<<"bug\n" using namespace std; const int MAXN = 1e7+7; const int MAXM = 1e9+7; long long phi[MAXN]; long long prime[MAXN]; int num_prime; void get_euler(int n) { num_prime=0; memset(phi,0,sizeof(phi)); phi[1]=0; for(long long i=2; i<=n; ++i) if(!phi[i]) { prime[num_prime++]=i; for(long long j=i; j<=n; j+=i) { if(!phi[j]) phi[j]=j; phi[j]=phi[j]/i*(i-1); } } } int main() { long long n; //get_euler(); scanf("%I64d",&n); { get_euler(n); long long ans=0; for(int i=2; i<=n; ++i) phi[i]+=phi[i-1]; for(int i=0; i<num_prime; ++i) ans+=phi[n/prime[i]]; ans=ans*2+num_prime; printf("%lld\n",ans); //cout<<ans<<endl; } return 0; }
相关文章推荐
- 【Unity开发】Unity中触摸和鼠标操作的几个问题
- 多线程(二)
- 设计模式之:简单工厂模式
- 简单web服务器学习总结
- 设计模式之单例模式
- maven中的依赖范围
- UIControl
- 设计模式
- 基于FPGA的飞机的小游戏
- 4. Android框架和工具之 android-async-http
- Java通过缓冲区复制一个.java文件。
- 心形图。撩妹用
- Light oj 1112 - Curious Robin Hood【单点更新】
- vsftpd:500 OOPS: vsftpd: refusing to run with writable root inside chroot ()错误的解决方法
- 面向对象思想设计原则
- 域名后面多一“点”带来的问题
- 自己搭建Wifi Pineapple Mark V
- ViewGroup2——自定义实现流式布局
- Ubuntu搭建Openstack平台(kilo)(三.glance)
- POJ 2632 Crashing Robots