莫比乌斯反演及其应用-小结

莫比乌斯反演的形式:


另一种描述是:


一种是和所有的约数有关一种是和所有的倍数有关

关于莫比乌斯函数mu,他的定义如下:


这个莫比乌斯函数有一些性质:

(1)


(2)


-----------------------分块优化----------------------

如果最后反演得到的f(x)大致为 

f(x)=sigma(     n/i * m/i  *xxxx    )


则可以分块优化把复杂度降到sqrt(n)




范例代码:

//找[1,n],[1,m]内互质的数的对数,分块优化
ll solve(ll n,ll m )
{
    if (n>m)swap(n,m);
    ll ret=0;
    for (int i=1,last;i<=n;i=last+1)
    {
        last=min(n/(n/i),m/(m/i));
        ret+=(sum[last]-sum[i-1])*(n/i)*(m/i);
    }
    return ret;
}
其中sum为mu的前缀和


莫比乌斯函数 线性筛代码:o(n)

const int  N=50000;
bool is_prime[N+500];
int prime[N+50];
int mu[N+50];
ll sum[N+50];
ll tot;
void Moblus()
{
    tot = 0;
    mu[1] = 1;
    for(ll i = 2; i < N; i++)
    {
        if(!is_prime[i])
        {
            prime[tot++] = i;
            mu[i] = -1;
        }
        for(ll j = 0; j < tot && i*prime[j] < N; j++)
        {
            is_prime[i*prime[j]] = 1;
            if(i % prime[j])
            {
                mu[i*prime[j]] = -mu[i];
            }
            else
            {
                mu[i*prime[j]] = 0;
                break;
            }
        }
    }
}



nlogn 筛法 (因子倍增法):

void pre()  // nlogn+n+nlogn
{
    for (int i=1; i<=N; i++)
        for (ll j=i ; j<=N; j+=i)
            ud[j].x+=i; 
}


预处理:


通常求这部分的时候,由于我们是枚举D,不可能在枚举某个d时去找所有约数求值,

往往 是先预处理,遍历所有的i=1:n,利用因子倍增法预处理出所有的F(i)*u(d/i)。




你可能感兴趣的:(莫比乌斯反演及其应用-小结)