Luogu P2568 GCD

Posted cjjsb

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Luogu P2568 GCD相关的知识,希望对你有一定的参考价值。

我们首先发现这样肯定是做不了的,所以我们枚举为(gcd(x,y)=d)(d)

然后考虑以下的性质:

(为素数gcd(x,y)=1 Leftrightarrow gcd(px,py)=p(p为素数))

这个很显然吧,因此当我们枚举素数(d)时只需要计算(x,yin[1,lfloorfrac{n}{d} floor])(gcd(x,y)=1)有序(x,y)对数即可。

我们假定(x<=y),那么很容易结合欧拉函数的性质得出此时对答案的贡献为(2cdotsum_{i=1}^{lfloorfrac{n}{d} floor}phi(i)-1)

这个比较显然吧,假定(iin[1,lfloorfrac{n}{d} floor])为较大的那个,所以无序的对数就是(phi(i)),由于有序所以乘2。最后注意一下((1,1))会被计算两次要减去。

最后给欧拉函数记一个前缀和即可。

CODE

#include<cstdio>
#define RI register int
using namespace std;
const int P=1e7;
int prime[P+5],phi[P+5],cnt,n; long long ans,sum[P+5]; bool vis[P+5];
inline void resolve(int x)
{
    vis[1]=phi[1]=1; sum[1]=2; for (RI i=2;i<=n;++i)
    {
        if (!vis[i]) prime[++cnt]=i,phi[i]=i-1;
        for (RI j=1;j<=cnt&&i*prime[j]<=n;++j)
        {
            vis[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; }
        }
        sum[i]=sum[i-1]+(phi[i]<<1);
    }
}
int main()
{
    RI i; scanf("%d",&n); for (resolve(n),i=1;i<=cnt;++i)
    ans+=sum[n/prime[i]]-1; return printf("%lld",ans),0;
}

以上是关于Luogu P2568 GCD的主要内容,如果未能解决你的问题,请参考以下文章

P2568 GCD

P2568 GCD

Copy自某谷题解UVA11417 GCD

luogu2658 GCD(莫比乌斯反演/欧拉函数)

「Luogu2257」YY的GCD

luogu2568GCD题解--欧拉函数