[BZOJ2818]Gcd(莫比乌斯反演)

题目:

我是超链接

题解:

据说是数论,然而喵喵喵毅然决然写了莫比乌斯反演
和上一道题目的柿子过程差不多啊。。。
[BZOJ2818]Gcd(莫比乌斯反演)_第1张图片
其实到这个位置已经能做了,但是枚举每一个t挺费劲,我们可以考虑这个这里写图片描述相等的部分
设分子为N,我们说相等的部分的值是N/t,等于这个值的最大在N/(N/t)的位置
那么我们对于每一个相等的部分计算,对μ求前缀和算一下

代码:

#include 
#include 
#define LL long long
using namespace std;
const int N=1e7;
int n,pri[N+5],num,mu[N+5];
LL ans;
bool ss[N+5];
void get_mu()
{
    mu[1]=1;
    for (int i=2;i<=n;i++)
    {
        if (!ss[i])
        {
            pri[++num]=i;
            mu[i]=-1;
        }
        for (int j=1;j<=num && pri[j]*i<=n;j++)
        {
            ss[pri[j]*i]=1;
            if (i%pri[j]==0)
            {
                mu[pri[j]*i]=0;
                break;
            }
            mu[pri[j]*i]=-mu[i];
        }
        mu[i]+=mu[i-1];
    }
}
int main()
{   
    int d,t,j;
    scanf("%d",&n);
    get_mu();
    for (d=1;d<=num && n/pri[d];d++)
    {
        int N=n/pri[d];
        for (t=1;t<=N;t=j+1)
        {
            j=min(N,N/(N/t));
            ans+=(LL)(N/t)*(N/t)*(mu[j]-mu[t-1]);
        }
    }
    printf("%lld",ans);
}

你可能感兴趣的:(莫比乌斯反演)