关于莫比乌斯反演的几个题目(更新中)

网络赛中有一道数论题出现了莫比乌斯反演这个概念,今天就学了一下

当g(x) = sigma{f(d),d|x}

则f(x) = sigma{mu(d)*g(x/d),d|x} 

其中mu(d)为莫比乌斯函数,详细了解请看具体数学吧

1.SPOJ VLATTICE

果断不会的,就翻了题解,这道题题解刚开始都看不懂。

后来才知道,莫比乌斯函数有另一种形式

当g(x) = sigma{f(d),x|d}

则f(x) = sigma{mu(d/x)*g(d),x|d}

这道题可以构造f(x) 为gcd(i,j,k) = x的个数,g(x) 为满足 x|gcd(i,j,k) 的个数

由于gcd(x) = [n/x]^3,所以计算f(1)即可。

另外,读题,这道题可以令一个变量为0,也就是三维变二维,还有(0,0,1),(0,1,0),(1,0,0)三个情况算上

#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <cmath>
#include <cstdlib>

#define ll long long
#define N 1000005
#define ss(a) scanf("%d",&a)
#define cl(a) memset(a,-1,sizeof(a))
#define pb push_back

using namespace std;

int mu[N],f[N],a[N];
vector<int>rec;

void prime()
{
    int i,j;
    cl(mu);
    mu[1]=1;
    rec.pb(1);
    for (i=2;i<N;i++)
    {
        if (!a[i])
        {
            mu[i]=-1;
            for (j=2*i;j<N;j+=i) a[j]++;
            ll k=1ll*i*i;
            if (k<N)
            {
                for (j=1;j*k<N;j++) mu[j*k]=0;
            }
        }   
        else if (mu[i]!=0) 
        {
            if (a[i]%2==0) mu[i]=1;
            else mu[i]=-1;    
        }
        if (mu[i]!=0) rec.pb(i); 
    }
}

ll js(int n)
{
    ll sum=3,t,x,i;
    for (i=0;i<rec.size()&&rec[i]<=n;i++)
    {
        t=rec[i];
        x=n/t; 
        sum=sum+x*x*x*mu[t];
        sum=sum+x*x*mu[t]*3;
    }
    return sum;
}

int main()
{
    int i,T,n;
    prime();
    ss(T);
    while (T--)
    {
        ss(n);
        cout<<js(n)<<endl;
    }
    return 0;
}



阅读更多
换一批

没有更多推荐了,返回首页