刚写完积性函数,今天两更,更完睡觉。
不知道迪利克雷卷积的去隔壁上课。
怎么求莫比乌斯函数也在隔壁讲了。
并且我们知道了 u ∗ 1 = e u*1=e u∗1=e。
现在我们来学习怎么用莫比乌斯函数。
没错,那就是莫比乌斯反演了。
什么是莫比乌斯反演?
我们设 f f f为数论函数, f f f的和函数的值为 F ( n ) = ∑ d ∣ n f ( d ) F(n)=\sum_{d|n}f(d) F(n)=∑d∣nf(d),它的值是由 f f f决定的。
现在我们要逆转这种关系,让我们得到用 F F F来求解 f f f的办法。
这就是莫比乌斯反演了。
我们发现原式其实是 F = 1 ∗ f F=1*f F=1∗f,两边同乘 μ \mu μ,就得到了 f = μ ∗ F f=\mu *F f=μ∗F。
其实这就是莫比乌斯反演的一个公式了。
当然,更具体的公式是长这样的,
已知 F ( n ) = ∑ d ∣ n f ( d ) F(n)=\sum_{d|n}f(d) F(n)=∑d∣nf(d),则有 f ( n ) = ∑ d ∣ n μ ( d ) F ( n / d ) f(n)=\sum_{d|n}\mu(d)F(n/d) f(n)=∑d∣nμ(d)F(n/d)(或者 ∑ d ∣ n μ ( n / d ) F ( n ) \sum_{d|n}\mu(n/d)F(n) ∑d∣nμ(n/d)F(n))。
那么还有第二个公式,
已知 F ( n ) = ∑ n ∣ d f ( d ) F(n)=\sum_{n|d}f(d) F(n)=∑n∣df(d),则有 f ( n ) = ∑ n ∣ d μ ( d / n ) F ( d ) f(n)=\sum_{n|d}\mu(d/n)F(d) f(n)=∑n∣dμ(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)的值了。
原理其实就这些了,这东西还是得多做题才能搞清楚。
给出两个区间 [ 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 a⩽x⩽b且 c ⩽ y ⩽ d c\leqslant y\leqslant d c⩽y⩽d。 ( 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) (1⩽a⩽b⩽1e7,1⩽c⩽d⩽1e7)
有两种做法。
先来正经的莫比乌斯反演。
我们令 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 a⩽x⩽b,c⩽y⩽d的对数。
然后令 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 a⩽x⩽b,c⩽y⩽d的对数。
会发现 F ( t ) F(t) F(t)可以直接求, t ∣ g c d ( x , y ) t|gcd(x,y) t∣gcd(x,y)即为 t ∣ x t|x t∣x且 t ∣ y t|y t∣y,也就是有多少个 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)=(⌊tb⌋−⌈ta⌉+1)(⌊td⌋−⌈tc⌉+1)
且有 F ( n ) = ∑ n ∣ t f ( t ) F(n)=\sum_{n|t}f(t) F(n)=∑n∣tf(t),
反演后变为 f ( n ) = ∑ n ∣ t μ ( t / n ) F ( t ) f(n)=\sum_{n|t}\mu(t/n)F(t) f(n)=∑n∣tμ(t/n)F(t)。
那么我们要求的 f ( 1 ) = ∑ 1 ∣ t μ ( t ) F ( t ) 。 f(1)=\sum_{1|t}\mu(t)F(t)。 f(1)=∑1∣tμ(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] ∑d∣nμ(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=ab∑y=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=ab∑y=cd∑t∣gcd(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=ab∑y=cd∑t∣x,t∣yμ(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[t∣x]∑y=cd[t∣y]
= ∑ 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)(⌊tb⌋−⌈ta⌉+1)(⌊td⌋−⌈tc⌉+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;
}
这个问题,用来讨论 φ = μ ∗ 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)(⌊tn⌋−⌈tn⌉+1)(⌊tn⌋−⌈t1⌉+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] ⌊tn⌋−⌈tn⌉+1=[t∣n],
⌈ 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)=∑t∣nμ(t)t,即 φ = μ ∗ i d \varphi=\mu*id φ=μ∗id。
还有很多类型,要多做题。
下课,睡了睡了