【题解】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;
}
posted @ 2019-04-09 22:22  章鱼那个哥  阅读(84)  评论(0编辑  收藏  举报