【题解】P2568 GCD
\(Description:\)
求x,y小于n中gcd(x,y)为质数的对数
\(Sample\) \(Input:\)
4
\(Sample\) \(Output:\)
4
\(Hint:\)
x,y互换算不同
n<=1e7
这题,我一看…………
好一题欧拉函数。
啊,什么啊 ? 欧拉函数?
没错,我们化化式子。
$\sum_{p}{Prime}\sum_{i=1}\sum_{j=1}^{p} $ $ 1(gcd(i,j)=p)/0(gcd(i,j!=p))$
gcd化简:
\(\sum_{p}^{Prime}\sum_{i=1}^{n/p}\sum_{j=1}^{n/p}gcd(i,j)=1\)
欧拉函数化简:
\(\sum_{p}^{Prime}\sum_{i=1}^{n/p}2*\phi(i)-1\)
那么在对\(\phi(i)\)前缀和优化一下就可以了。
顺便提一提:这题别开太多没用的东西,别随手longlong
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
int n,cnt;
LL ans;
const int N=1e7;
bool v[N+5];
int main(){
scanf("%d",&n);
int *p,*phi;
p=new int [n+5];
phi=new int [n+5];
LL *s;
s=new LL [n+5];
memset(p,0,sizeof(p));
memset(phi,0,sizeof(phi));
memset(s,0,sizeof(s));
v[1]=1;phi[1]=1;
for(int i=2;i<=n;++i){
if(!v[i]) p[++cnt]=i,phi[i]=i-1;
for(int j=1;j<=cnt && i*p[j]<=n;++j){
v[i*p[j]]=1;
if(i%p[j]!=0) phi[i*p[j]]=phi[i]*phi[p[j]];
else { phi[i*p[j]]=phi[i]*p[j];break;}
}
}
for(int i=1;i<=n;++i) s[i]=(LL)(s[i-1]+phi[i]);
for(int i=1;i<=cnt;++i) ans+=s[n/p[i]]*2-1;
delete [] p;
delete [] phi;
delete [] s;
printf("%lld\n",ans);
return 0;
}