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

题目:

我是超链接

题解:

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

代码:

#include <cstdio>
#include <iostream>
#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);
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值