【bzoj2818】Gcd 欧拉函数
2016-11-21 13:06
435 查看
AC通道:http://www.lydsy.com/JudgeOnline/problem.php?id=2818
【题解】
用f[i]表示1~i中gcd(a,b)=1的数对(a,b)的对数,那么显然 f[i] = 1+2* sigma(phi[j]) 1<j<=i
那么ans = sigma(f[N/p]) p为小于N的素数
原理很简单,即如果gcd(a,b)=1,那么gcd(a*p,b*p)=p
/************* bzoj 2818 by chty 2016.11.3 *************/ #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<ctime> #include<cmath> #include<algorithm> using namespace std; #define MAXN 10000010 int n,cnt,prime[MAXN],check[MAXN],phi[MAXN]; long long f[MAXN],ans; inline int read() { int x=0,f=1; char ch=getchar(); while(!isdigit(ch)) {if(ch=='-') f=-1; ch=getchar();} while(isdigit(ch)) {x=x*10+ch-'0'; ch=getchar();} return x*f; } void get() { phi[1]=1; for(int i=2;i<=n;i++) { if(!check[i]) {prime[++cnt]=i; phi[i]=i-1;} for(int j=1;j<=cnt&&prime[j]*i<=n;j++) { check[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;} } } } int main() { freopen("cin.in","r",stdin); freopen("cout.out","w",stdout); n=read(); get(); f[1]=1; for(int i=2;i<=n;i++) f[i]=f[i-1]+2*phi[i]; for(int i=1;i<=cnt;i++) if(prime[i]<n) ans+=f[n/prime[i]]; printf("%lld\n",ans); return 0; }
相关文章推荐
- BZOJ 2818 GCD(欧拉函数)
- 【bzoj 2818】Gcd(欧拉函数)
- bzoj 2818 Gcd 【欧拉函数】
- BZOJ 2818: Gcd [欧拉函数 质数 线性筛]【学习笔记】
- 【BZOJ2818】Gcd(莫比乌斯反演,欧拉函数)
- bzoj2818 Gcd(欧拉函数前缀和)
- bzoj 2818 gcd 线性欧拉函数
- BZOJ 2818 Gcd (莫比乌斯反演 或 欧拉函数)
- 【bzoj2818】Gcd 欧拉函数
- bzoj2818: Gcd(欧拉函数)
- [bzoj2818]Gcd 欧拉函数
- BZOJ2818 Gcd(欧拉函数)
- bzoj 2818: Gcd 线性筛求欧拉函数
- BZOJ 2818: Gcd区间内最大公约数 为素数的对数(欧拉函数的应用)
- BZOJ 2818 Gcd(gcd(x,y)为素数/欧拉函数/莫比乌斯反演)
- BZOJ 2818: Gcd( 欧拉函数 )
- BZOJ2818: Gcd 欧拉函数求前缀和
- [BZOJ 2818] Gcd 线性筛+欧拉函数前缀和
- bzoj 2818 Gcd(欧拉函数 | 莫比乌斯反演)
- Bzoj-2818 Gcd 欧拉函数