[luogu P2586] GCD 解题报告 (莫比乌斯反演|欧拉函数)

Posted xxzh

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[luogu P2586] GCD 解题报告 (莫比乌斯反演|欧拉函数)相关的知识,希望对你有一定的参考价值。

题目链接:https://www.luogu.org/problemnew/show/P2568#sub

题目大意:

计算?$sum_{x=1}^nsum_{y=1}^n [gcd(x,y)==prime]?$

题解:

解法一:莫比乌斯反演套路题

技术分享图片

其实这样就可以了,但是还可以优化一下子

??T=dp

?技术分享图片

整除分块就好了,其实这就和 yy的gcd 一样了

解法二:欧拉函数

考虑上面的第一个式子?可以化简成

?技术分享图片

tot是n以内质数的数量

这是因为考虑到每次都两次计算了?$varphi(1)$

#include<algorithm>
#include<cstring>
#include<cstdio>
#include<iostream>
using namespace std;
typedef long long ll;

const int N=1e7+15;
int n,tot;
ll ans;
int prime[5000000];
ll phi[N];
bool vis[N];
void get_phi()
{
    phi[1]=1;
    for (int i=2;i<=n;i++)
    {
        if (!vis[i]) {phi[i]=i-1;prime[++tot]=i;}
        for (int j=1;j<=tot&&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;
            }
        }
    }
    for (int i=2;i<=n;i++) phi[i]=phi[i-1]+phi[i];
}
int main()
{
    scanf("%d",&n);
    get_phi();
    //for (int i=1;i<=n;i++) printf("%d ",phi[i]);
    for (int i=1;i<=tot;i++)
    {
        ans+=phi[n/prime[i]];
    }
    printf("%lld
",ans*2-tot);
    return 0;
}

 

以上是关于[luogu P2586] GCD 解题报告 (莫比乌斯反演|欧拉函数)的主要内容,如果未能解决你的问题,请参考以下文章

「Luogu2257」YY的GCD

cogs2745[济南集训 2017] 求gcd之和解题报告

luogu P1890ybtojRMQ问题课堂过关例题2静态区间 & gcd区间

codeforces 798C.Mike and gcd problem 解题报告

解题报告:luogu P1160

解题报告:luogu P2299