莫比乌斯反演的形式:
另一种描述是:
一种是和所有的约数有关一种是和所有的倍数有关
关于莫比乌斯函数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)。