莫比乌斯反演

前言:

刚写完积性函数,今天两更,更完睡觉。
 

莫比乌斯函数 μ ( n ) \mu(n) μ(n)

不知道迪利克雷卷积的去隔壁上课。
怎么求莫比乌斯函数也在隔壁讲了。
并且我们知道了 u ∗ 1 = e u*1=e u1=e
 
现在我们来学习怎么用莫比乌斯函数。
没错,那就是莫比乌斯反演了。
 

莫比乌斯反演:

什么是莫比乌斯反演?
我们设 f f f为数论函数, f f f的和函数的值为 F ( n ) = ∑ d ∣ n f ( d ) F(n)=\sum_{d|n}f(d) F(n)=dnf(d),它的值是由 f f f决定的。
现在我们要逆转这种关系,让我们得到用 F F F来求解 f f f的办法。
这就是莫比乌斯反演了。
我们发现原式其实是 F = 1 ∗ f F=1*f F=1f,两边同乘 μ \mu μ,就得到了 f = μ ∗ F f=\mu *F f=μF
 
其实这就是莫比乌斯反演的一个公式了。
当然,更具体的公式是长这样的,
已知 F ( n ) = ∑ d ∣ n f ( d ) F(n)=\sum_{d|n}f(d) F(n)=dnf(d),则有 f ( n ) = ∑ d ∣ n μ ( d ) F ( n / d ) f(n)=\sum_{d|n}\mu(d)F(n/d) f(n)=dnμ(d)F(n/d)(或者 ∑ d ∣ n μ ( n / d ) F ( n ) \sum_{d|n}\mu(n/d)F(n) dnμ(n/d)F(n))。

那么还有第二个公式,
已知 F ( n ) = ∑ n ∣ d f ( d ) F(n)=\sum_{n|d}f(d) F(n)=ndf(d),则有 f ( n ) = ∑ n ∣ d μ ( d / n ) F ( d ) f(n)=\sum_{n|d}\mu(d/n)F(d) f(n)=ndμ(d/n)F(d)
(这个证明略了)
 
也就是说,当我们要求 f ( n ) f(n) f(n),但是 f ( n ) f(n) f(n)并不好求,但是 F ( n ) F(n) F(n)却意外的好求。那么,我们学会莫比乌斯反演后,就可以通过这个 F ( n ) F(n) F(n),来得到 f ( n ) f(n) f(n)的值了。
 
原理其实就这些了,这东西还是得多做题才能搞清楚。

应用:

问题1:

给出两个区间 [ a , b ] [a,b] [a,b] [ c , d ] [c,d] [c,d],求有多少对互质的正整数 x x x y y y满足 a ⩽ x ⩽ b a\leqslant x\leqslant b axb c ⩽ y ⩽ d c\leqslant y\leqslant d cyd ( 1 ⩽ a ⩽ b ⩽ 1 e 7 , 1 ⩽ c ⩽ d ⩽ 1 e 7 ) (1\leqslant a\leqslant b\leqslant 1e7,1\leqslant c\leqslant d\leqslant 1e7) (1ab1e7,1cd1e7)

解:

有两种做法。
 
先来正经的莫比乌斯反演。
我们令 f ( t ) f(t) f(t)表示满足 t = g c d ( x , y ) t=gcd(x,y) t=gcd(x,y),且 a ⩽ x ⩽ b , c ⩽ y ⩽ d a\leqslant x\leqslant b,c\leqslant y\leqslant d axb,cyd的对数。
然后令 F ( t ) F(t) F(t)表示满足 t ∣ g c d ( x , y ) t|gcd(x,y) tgcd(x,y),且 a ⩽ x ⩽ b , c ⩽ y ⩽ d a\leqslant x\leqslant b,c\leqslant y\leqslant d axb,cyd的对数。
会发现 F ( t ) F(t) F(t)可以直接求, t ∣ g c d ( x , y ) t|gcd(x,y) tgcd(x,y)即为 t ∣ x t|x tx t ∣ y t|y ty,也就是有多少个 x x x d d d整除,有多少个 y y y d d d整除,再乘起来。得到 F ( t ) = ( ⌊ b t ⌋ − ⌈ a t ⌉ + 1 ) ( ⌊ d t ⌋ − ⌈ c t ⌉ + 1 ) F(t)=(\left \lfloor \frac{b}{t}\right \rfloor-\left \lceil \frac{a}{t}\right \rceil+1)(\left \lfloor \frac{d}{t}\right \rfloor-\left \lceil \frac{c}{t}\right \rceil+1) F(t)=(tbta+1)(tdtc+1)
且有 F ( n ) = ∑ n ∣ t f ( t ) F(n)=\sum_{n|t}f(t) F(n)=ntf(t)
反演后变为 f ( n ) = ∑ n ∣ t μ ( t / n ) F ( t ) f(n)=\sum_{n|t}\mu(t/n)F(t) f(n)=ntμ(t/n)F(t)
那么我们要求的 f ( 1 ) = ∑ 1 ∣ t μ ( t ) F ( t ) 。 f(1)=\sum_{1|t}\mu(t)F(t)。 f(1)=1tμ(t)F(t)
接下来就是枚举 t t t,上限是 m i n ( b , d ) min(b,d) min(b,d)
 
再说一个另一个做法。
观察表达式 [ g c d ( x , y ) = 1 ] [gcd(x,y)=1] [gcd(x,y)=1]
这让我们想起单位函数 e ( n ) = [ n = 1 ] e(n)=[n=1] e(n)=[n=1]
然后 e = μ ∗ 1 e=\mu *1 e=μ1,可以得到一个重要的表达式 ∑ d ∣ n μ ( d ) = [ n = 1 ] \sum_{d|n}\mu(d)=[n=1] dnμ(d)=[n=1]
然后我们开始推公式,
∑ x = a b ∑ y = c d [ g c d ( x , y ) = 1 ] \sum_{x=a}^{b}\sum_{y=c}^{d}[gcd(x,y)=1] x=aby=cd[gcd(x,y)=1]
= ∑ x = a b ∑ y = c d ∑ t ∣ g c d ( x , y ) μ ( t ) =\sum_{x=a}^{b}\sum_{y=c}^{d}\sum_{t|gcd(x,y)}\mu(t) =x=aby=cdtgcd(x,y)μ(t)
= ∑ x = a b ∑ y = c d ∑ t ∣ x , t ∣ y μ ( t ) =\sum_{x=a}^{b}\sum_{y=c}^{d}\sum_{t|x,t|y}\mu(t) =x=aby=cdtx,tyμ(t)
= ∑ t = 1 m i n ( b , d ) μ ( t ) ∑ x = a b [ t ∣ x ] ∑ y = c d [ t ∣ y ] =\sum_{t=1}^{min(b,d)}\mu(t)\sum_{x=a}^{b}[t|x]\sum_{y=c}^{d}[t|y] =t=1min(b,d)μ(t)x=ab[tx]y=cd[ty]
= ∑ t = 1 m i n ( b , d ) μ ( t ) ( ⌊ b t ⌋ − ⌈ a t ⌉ + 1 ) ( ⌊ d t ⌋ − ⌈ c t ⌉ + 1 ) =\sum_{t=1}^{min(b,d)}\mu(t)(\left \lfloor \frac{b}{t}\right \rfloor-\left \lceil \frac{a}{t}\right \rceil+1)(\left \lfloor \frac{d}{t}\right \rfloor-\left \lceil \frac{c}{t}\right \rceil+1) =t=1min(b,d)μ(t)(tbta+1)(tdtc+1)
然后就好了。
这个上手起来比较容易,看到 [ g c d ( x , y ) = 1 ] [gcd(x,y)=1] [gcd(x,y)=1]就套进去,然后把 g c d gcd gcd提到前面来枚举,如果是 [ g c d ( x , y ) = k ] [gcd(x,y)=k] [gcd(x,y)=k],就化成等于 1 1 1的情况。
但是认真学反演还是有必要的。
 
带整除的,还可以用数论分块优化到 1 e 7 \sqrt{1e7} 1e7 ,但是这里预处理莫比乌斯就已经跑了这么多了,所以就不搞了。
上代码:

#include
#include
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
typedef pair<int,int> P;
const ll MAXN=10000010;

ll prime[MAXN+10],notPrime[MAXN+10],mu[MAXN+10],tot;
void initMu(int n)
{
    notPrime[1]=mu[1]=1;
    for(int i=2;i<=n;i++)
    {
        if(!notPrime[i])prime[tot++]=i,mu[i]=-1;
        for(int j=0;j<tot&&i*prime[j]<=n;j++)
        {
            notPrime[i*prime[j]]=1;
            if(i%prime[j])mu[i*prime[j]]=-mu[i];
            else {mu[i*prime[j]]=0;break;}
        }
    }
}

int main()
{
    initMu(MAXN);
    ll a,b,c,d;
    cin>>a>>b>>c>>d;
    ll ans=0;
    for(ll i=1;i<=max(b,d);i++)
    {
        ans+=mu[i]*(b/i-(a+i-1)/i+1)*(d/i-(c+i-1)/i+1);
    }
    cout<<ans<<endl;
    return 0;
}

 
 

问题2:

这个问题,用来讨论 φ = μ ∗ i d \varphi=\mu*id φ=μid这个式子。

解:

就依据这个式子,我们反手来一个莫比乌斯反演求欧拉函数。(虽然实际不这样求,但是推公式会有用到这个函数关系)
 
好像是上一个问题的简化版。。
就是求区间 [ 1 , n ] [1,n] [1,n] [ n , n ] [n,n] [n,n]两个区间内互质的对数。
那么我们依据上一题的推导,得到了公式,
φ ( n ) = ∑ t = 1 n μ ( t ) ( ⌊ n t ⌋ − ⌈ n t ⌉ + 1 ) ( ⌊ n t ⌋ − ⌈ 1 t ⌉ + 1 ) \varphi(n)=\sum_{t=1}^{n}\mu(t)(\left \lfloor \frac{n}{t}\right \rfloor-\left \lceil \frac{n}{t}\right \rceil+1)(\left \lfloor \frac{n}{t}\right \rfloor-\left \lceil \frac{1}{t}\right \rceil+1) φ(n)=t=1nμ(t)(tntn+1)(tnt1+1)
然后发现了一些神奇的东西。
⌊ n t ⌋ − ⌈ n t ⌉ + 1 = [ t ∣ n ] \left \lfloor \frac{n}{t}\right \rfloor-\left \lceil \frac{n}{t}\right \rceil+1=[t|n] tntn+1=[tn]
⌈ 1 t ⌉ = 1 \left \lceil \frac{1}{t}\right \rceil=1 t1=1
所以原式变成了 φ ( n ) = ∑ t ∣ n μ ( t ) t \varphi(n)=\sum_{t|n}\mu(t)t φ(n)=tnμ(t)t,即 φ = μ ∗ i d \varphi=\mu*id φ=μid
 
 
 
 
 
还有很多类型,要多做题。
下课,睡了睡了

你可能感兴趣的:(数论,莫比乌斯反演,acm竞赛)