bzoj2818Gcd 莫比乌斯反演

其实这题可以用欧拉函数做,我只是闲得蛋疼用反演而已。。
bzoj2818Gcd 莫比乌斯反演_第1张图片
最后那一坨分块搞一下就好了

#include
#include
#include
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
typedef long long ll;
const int N=1e7+5;
ll n,ans,p[N],pri[N],mu[N];
int main()
{
    int tot=0;
    scanf("%lld",&n);
    mu[1]=1;
    fo(i,2,n)
    {
        if (!p[i])
        {
            pri[++tot]=i;
            mu[i]=-1;
        }
        fo(j,1,tot)
        {
            if (pri[j]*i>n)break;
            p[i*pri[j]]=1;
            if (i%pri[j]==0)
            {
                mu[i*pri[j]]==0;
                break;
            }
            else mu[i*pri[j]]=-mu[i];
        }
        mu[i]+=mu[i-1];
    }
    for(ll d=1;d<=tot&&pri[d]<=n;++d)
    {
        ll m=(ll)n/pri[d];
        ll j=0;
        for(ll i=1;i<=m;i=j+1)
        {
            j=min(m,m/(m/i));
            ans+=(m/i)*(m/i)*(mu[j]-mu[i-1]);
        }
    }
    printf("%lld\n",ans);
} 

你可能感兴趣的:(bzoj,莫比乌斯反演,欧拉函数)