数论 —— 莫比乌斯反演

【反演】

假设我们手头有个数列 F,通过某种变换 H,可以得到函数 G。,即:F \diamond H->G

但现在只有函数 G,需要求 F,那么我们就需要寻找一种变换 H^{-1},使得 G 在经过这种变换后能够获得 F,这个过程即为反演,即:G \diamond H^{-1}->F

【整除分块】

对于式子:\sum_{i=1}^n[\frac{n}{i}],其时间复杂度为 O(n),当有多组数据时,O(n) 并非正确的时间复杂度,此时有一种时间复杂度为 O(√n) 的算法:整除分块

对于每一个 [\frac{n}{i}] 通过打表发现,很多 [\frac{n}{i}] 的值是相同的,它们呈一个块状分布,对每一个值相同的块,它的最后一个数是:\begin{bmatrix}n \\- \\ [\frac{n}{i}] \end{bmatrix}

有时候,可能式子不一定是一个裸的整除分块,可能会与某些积性函数相乘,这时就需要对这些函数统计一个前缀和。因为,每当我们使用整除分块跳过一个区间的时候,其所对应的函数值也跳过了一个区间,所以就需要乘上那一个区间的函数值

实现

int res=0;
for(int left=1,right;left<=n;left=right+1){
    right=n/(n/left);
    res+=(righr-left+1)*(n/left);
}

对于式子:\sum_{i=1}^n\sum_{j=1}^m\left \lfloor \frac{n}{i} \right \rfloor\left \lfloor \frac{m}{j} \right \rfloor,其时间复杂度为 O(n^2),同样可以使用整除分块的做法来降低时间复杂度

int res=0;
int minn=min(n,m);
for(int left=1,right;left<=minn;left=right+1){
    right=min(n/(n/left),m/(m/left));
    res+=(righr-left+1)*(n/left)*(m/left);
}

【莫比乌斯函数】

1.定义

\mu (d)\left\{\begin{matrix}1,\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:d=1\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\: \\ (-1)^k,d=\prod ^k_{i=1}p_i^{a_i},\prod_{i=1}^ka_i=1 \\ 0,\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:\:otherwise \:\:\:\:\:\:\:\:\:\:\:\: \end{matrix}\right.

其中对于 \mu(d)=(-1)^k 的情况,d=p_1*p_2*...*p_k,且 p_1,p_2,...,p_k 均为互质素数

简单来说,其满足以下几点:

  • 定义域:N
  • 当 d 为 1 时:μ(1)=1
  • 当 d 是偶数个不同素数之积时:μ(d)=1
  • 当 d 是奇数个不同素数之积时:μ(d)=-1
  • 当 d 是素数时:μ(d)=-1
  • 当 d 存在平方因子时:μ(d)=0

2.性质

  • 莫比乌斯函数 μ(d) 为积性函数:μ(d) 可以线性筛
  • 对于任意正整数 n,有:\sum_{d|n}\mu(d)=\left\{\begin{matrix}1,n=1 \\ 0,n>1 \end{matrix}\right.,当且仅当 n=1 时计数的函数,可用于求 (i,j)=1 的问题
  • 对于任意正整数 n,有:\sum_{d|n}\frac{\mu(d)}{d}=\frac{\phi (n)}{n},其中 \phi (n) 为欧拉函数

3.实现

1)普通筛

int mu[N];
void getMu(){
    for(int i=1;i<N;++i)
        int target=(i==1?1:0);
        int delta=target-mu[i];
        mu[i]=delta;
        for(int j=2*i;j<N;j+=i)
            mu[j]+=delta;
    }
}

2)线性筛

int mu[N];
int prime[N];
bool bprime[N];
int cnt;
void getMu(int n){//线性筛求莫比乌斯函数
    cnt=0;
    mu[1]=1;//根据定义,μ(1)=1
    memset(bprime,false,sizeof(bprime));

    for(int i=2;i<=n;i++){//求2~n的莫比乌斯函数
        if(!bprime[i]){
            prime[++cnt]=i;//存储质数
            mu[i]=-1;//i为质数时,μ(1)=-1
        }
        for(int j=1;j<=cnt&&i*prime[j]<=n;j++){//枚举i之前的素数个数
            bprime[i*prime[j]]=true;//不是质数
            if(i%prime[j])//i不是prime[j]的整数倍时,i*prime[j]就不会包含相同质因子
                mu[i*prime[j]]=-mu[i];//mu[k]=mu[i]*mu[prime[j]],因为prime[j]是质数,mu值为-1
            else{
                mu[i*prime[j]]=0;
                break;//留到后面再筛
            }
        }
    }
}

【莫比乌斯反演】

对于一些函数f(n),很难直接求出其值,但容易求出约数和或倍数和g(n),那么可以通过莫比乌斯反演来求得f(n)

莫比乌斯反演的题目通常能转化为(x,y)=1的计数问题,即用f(n)表示某一范围(x,y)=n的数对数量,g(n)表示某一范围内n|(x,y)的数对数量。

1.形式1

f(n) 和 g(n) 是定义在非负整数集合上的两个函数,那么有:

  • g(n)=\sum_{n|d}f(d) \Leftrightarrow f(n)= \sum_{n|d}u(\frac{d}{n})g(d)
  • g(n)=\sum_{d|n}f(d)\Leftrightarrow f(n)=\sum_{d|n}u(d)g(\frac{n}{d})

2.形式2

f(n) 和 g(n) 是定义在非负整数集合上的两个函数,且满足条件:f(n)=\sum_{d=1}^{[\frac{n}{i}]}g(i*d)

那么:g(i)=\sum_{d=1}^{[\frac{n}{i}]}f(i*d)\mu (d)

【例题】

  1. 约数研究(洛谷P1403)(整除分块)点击这里
  2. Sky Code(POJ-3904)(莫比乌斯反演+组合数)点击这里
  3. 完全平方数(HYSBZ-2440)(莫比乌斯函数应用+二分)点击这里
  4. GCD(HDU-1695)(莫比乌斯反演+容斥)点击这里
  5. YY的GCD(洛谷-P2257)(莫比乌斯反演+整除分块)点击这里
  6. ZAP-Queries(洛谷-P3455)(莫比乌斯反演+整除分块)点击这里
  7. Problem b(BZOJ-2301/HAOI-2011)(莫比乌斯反演+整除分块+容斥)点击这里
  8. 能量采集(HYSBZ-2005)(莫比乌斯反演+整除分块两次)点击这里
  9. Crash的数字表格(HYSBZ-2154)(LCM 的莫比乌斯反演)点击这里
  10. 算术(HDU-6715)(LCM 的莫比乌斯反演)点击这里
  11. Number Challenge(CF-235E)(约数个数的莫比乌斯反演+GCD打表)点击这里
  12. Easy Math(2018 ACM-ICPC 徐州赛区网络赛 D)(杜教筛+递归)点击这里
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值