G
N
I
D
A
O
L

笔记

莫比乌斯反演笔记

1:知识

设$ n=\prod\limits_{i=1}^k {p_i}^{c_i}$

1.常见函数表达式:

(1).单位函数: $\epsilon(n) = [n=1] $

(2).常函数: \(I(n) = 1\)

(3).幂函数: $ Id_k(n) = n^k $

(4).欧拉函数: $ \varphi(n) =\sum\limits_{i=1}^n[gcd(i,n) = 1] =n\prod\limits_{i=1}^k(1- \frac 1{p_i}) $

(5).莫比乌斯函数:

\[ \mu(n)= \begin{cases} 1, &{n=1} \\ (-1)^k &\forall i,c_i = 1 \\ 0 , &\text{otherwise} \end{cases} \]

(6).除数函数: $ \sigma_k(n) = \sum\limits_{d|n}d^k $

2.卷积常用公式

注:以下*为卷积

(1).$ \mu *I = \epsilon$

(2).$ \varphi * I = Id $

(3).$ Id_k * I = \sigma_k \Leftrightarrow Id_k = \sigma_k * \mu $

(4).$ (Id_k \cdot \mu) * Id_k = \epsilon $

(5).$ (Id_k \cdot \varphi) * Id_k = Id_{k+1} $

3.常见转换

(1).

\[\begin{aligned} \sum\limits_{i=1}^n \sum\limits_{j=1}^m[gcd(i,j) = k] &= \sum\limits_{i=1}^{\lfloor \frac nk \rfloor } \sum\limits_{j=1}^{\lfloor \frac mk \rfloor} [gcd(i,j)=1]\\ &= \sum\limits_{i=1}^{\lfloor \frac nk \rfloor } \sum\limits_{j=1}^{\lfloor \frac mk \rfloor} \sum\limits_{d|gcd(i,j)} \mu(d)\\ &= \sum\limits_{d=1}^{\lfloor \frac nk \rfloor } \mu(d)\sum\limits_{i=1}^{\lfloor \frac nk \rfloor } \sum\limits_{j=1}^{\lfloor \frac mk \rfloor} [d|gcd(i,j)]\\ &= \sum\limits_{d=1}^{\lfloor \frac nk \rfloor } \mu(d) \lfloor \frac n{kd} \rfloor \lfloor \frac m{kd} \rfloor\\ \end{aligned}\]

2:例题

(1).[Sdoi2017]数字表格

求 $ \prod\limits_{i=1}^n \prod\limits_{j=1}^m f(gcd(i,j)) mod 1e9+7 $,f(i)为斐波那契数列第i项

化简过程:

\[\begin{aligned} \prod\limits_{i=1}^n \prod\limits_{j=1}^m f(gcd(i,j)) &=\prod\limits_{k=1}^n\prod\limits_{i=1}^n \prod\limits_{j=1}^m f(k)*[gcd(i,j)=k]\\ &=\prod\limits_{k=1}^n\prod\limits_{i=1}^{\lfloor \frac nk \rfloor}\prod\limits_{j=1}^{\lfloor \frac mk \rfloor}f(k)*[gcd(i,j)=1]\\ &=\prod\limits_{k=1}^n f(k)^{\sum\limits_{i=1}^{\lfloor \frac nk \rfloor}\sum\limits_{j=1}^{\lfloor \frac mk \rfloor} [gcd(i,j)=1]}\\ \end{aligned}\]

先计算上标

\[\begin{aligned} \sum\limits_{i=1}^{\lfloor \frac nk \rfloor}\sum\limits_{j=1}^{\lfloor \frac mk \rfloor} [gcd(i,j)=1] &=\sum\limits_{i=1}^{\lfloor \frac nk \rfloor} \sum\limits_{j=1}^{\lfloor \frac mk \rfloor} \sum\limits_{d|gcd(i,j)}\mu(d)\\ &=\sum\limits_{d=1}^{\lfloor \frac nk \rfloor} \mu(d) \sum\limits_{i=1}^{\lfloor \frac nk \rfloor} \sum\limits_{j=1}^{\lfloor \frac mk \rfloor} [d|gcd(i,j)]\\ &=\sum\limits_{d=1}^{\lfloor \frac nk \rfloor} \mu(d) \lfloor \frac n{kd} \rfloor \lfloor \frac m{kd} \rfloor \end{aligned}\]

套回之前的式子

\[\begin{aligned} \prod\limits_{k=1}^n f(k)^{\sum\limits_{i=1}^{\lfloor \frac nk \rfloor}\sum\limits_{j=1}^{\lfloor \frac mk \rfloor} [gcd(i,j)=1]} &=\prod\limits_{k=1}^n f(k)^{\sum\limits_{d=1}^{\lfloor \frac nk \rfloor} \mu(d) \lfloor \frac n{kd} \rfloor \lfloor \frac m{kd} \rfloor}\\ &=\prod\limits_{T=1}^n ( \prod\limits_{d|T}f(d) ^ {\mu(\lfloor \frac Td \rfloor)}) ^{\lfloor \frac nT \rfloor \lfloor \frac mT \rfloor} \end{aligned}\]

(2).于神之怒加强版

求 $ {\sum\limits_{i=1}^n} {\sum\limits_{j=1}^m} \gcd(i,j)^k $

化简过程:

\[\begin{aligned} \sum\limits_{i=1}^n\sum\limits_{j=1}^mgcd(i,j)^k &=\sum\limits_{d=1}^n\sum\limits_{i=1}^n\sum\limits_{j=1}^md^k \cdot[gcd(i,j)=d]\\ &=\sum\limits_{d=1}^nd^k\sum\limits_{i=1}^n\sum\limits_{j=1}^m[gcd(i,j)=d] \end{aligned}\]

先把右半边的东西化简一下

\[\begin{aligned} \sum\limits_{i=1}^n\sum\limits_{j=1}^m[gcd(i,j)=d] &=\sum\limits_{i=1}^{\lfloor \frac nd \rfloor}\sum\limits_{j=1}^{\lfloor \frac md \rfloor}[gcd(i,j)=1]\\ &=\sum\limits_{i=1}^{\lfloor \frac nd \rfloor}\sum\limits_{j=1}^{\lfloor \frac md \rfloor}\sum\limits_{x|gcd(i,j)}\mu(x)\\ &=\sum\limits_{x=1}^{\lfloor \frac nd \rfloor}\mu(x)\sum\limits_{i=1}^{\lfloor \frac nd \rfloor}\sum\limits_{j=1}^{\lfloor \frac md \rfloor}[x|gcd(i,j)]\\ &=\sum\limits_{x=1}^{\lfloor \frac nd \rfloor}\mu(x)\lfloor \frac n{dx} \rfloor\lfloor \frac m{dx} \rfloor \end{aligned}\]

代回原式

\[\begin{aligned} \sum\limits_{d=1}^nd^k\sum\limits_{i=1}^n\sum\limits_{j=1}^m[gcd(i,j)=d] &=\sum\limits_{d=1}^nd^k\sum\limits_{x=1}^{\lfloor \frac nd \rfloor}\mu(x)\lfloor \frac n{dx} \rfloor\lfloor \frac m{dx} \rfloor\\ &=\sum\limits_{d=1}^n\lfloor \frac n{dx} \rfloor\lfloor \frac m{dx} \rfloor\sum\limits_{x=1}^{\lfloor \frac nd \rfloor}d^k\mu(x)\\ &=\sum\limits_{T=1}^n\lfloor \frac nT \rfloor\lfloor \frac mT \rfloor\sum\limits_{d|T}d^k\mu(\lfloor \frac Td \rfloor) \end{aligned}\]

(3).DZY Loves Math

对于正整数n,定义\(f(n)\)为n所含质因子的最大幂指数。例如\(f(1960)=f(2^3 \times 5^1 \times 7^2)=3\),\(f(10007) = 1\),\(f(1) = 0\)。给定正整数a,b,求下式的值:

\[\begin{aligned} \sum\limits_{i=1}^a\sum\limits_{j=1}^bf(gcd(i,j)) \end{aligned}\]

开始化简,首先我们枚举gcd(i,j)的值

\[\begin{aligned} \sum\limits_{i=1}^a\sum\limits_{j=1}^bf(gcd(i,j)) &=\sum\limits_{k=1}^n\sum\limits_{i=1}^a\sum\limits_{j=1}^bf(k)[gcd(i,j)==k]\\ &=\sum\limits_{k=1}^nf(k)\sum\limits_{i=1}^a\sum\limits_{j=1}^b[gcd(i,j)==k] \end{aligned}\]

然后就是大家都很熟悉的化简模板

\[\begin{aligned} \sum\limits_{k=1}^nf(k)\sum\limits_{i=1}^a\sum\limits_{j=1}^b[gcd(i,j)==k] &=\sum\limits_{k=1}^nf(k)\sum\limits_{i=1}^{\lfloor \frac nk \rfloor}\sum\limits_{j=1}^{\lfloor \frac mk \rfloor}[gcd(i,j)==1]\\ &=\sum\limits_{k=1}^nf(k)\sum\limits_{i=1}^{\lfloor \frac nk \rfloor}\sum\limits_{j=1}^{\lfloor \frac mk \rfloor}\sum\limits_{d|gcd(i,j)}\mu(d)\\ &=\sum\limits_{k=1}^nf(k)\sum\limits_{d=1}^{\lfloor \frac nk \rfloor}\mu(d)\sum\limits_{i=1}^{\lfloor \frac nk \rfloor}\sum\limits_{j=1}^{\lfloor \frac mk \rfloor}[d|gcd(i,j)]\\ &=\sum\limits_{k=1}^nf(k)\sum\limits_{d=1}^{\lfloor \frac nk \rfloor}\mu(d)\lfloor \frac n{kd} \rfloor \lfloor \frac m{kd} \rfloor \end{aligned}\]

设T=kd

\[\begin{aligned} \sum\limits_{k=1}^nf(k)\sum\limits_{d=1}^{\lfloor \frac nk \rfloor}\mu(d)\lfloor \frac n{kd} \rfloor \lfloor \frac m{kd} \rfloor &=\sum\limits_{T=1}^n \lfloor \frac nT \rfloor \lfloor \frac mT \rfloor \sum\limits_{d|T} f(d) \mu(\frac Td) \end{aligned}\]

设 $ \sum\limits_{d|T} f(d) \mu(\frac Td) $ 为 \(F(T)\)

我们就可以获得最终的式子 \(\sum\limits_{T=1}^n \lfloor \frac nT \rfloor \lfloor \frac mT \rfloor F(T)\)

接下来,就要想方法求 \(F(T)\)

\(F(T) = {\prod\limits_{i=1}^k p_i^{x_i}}\),\({d=\prod\limits_{i=1}^k} {p_i^{y_i}}\)

$ \mu(\frac Td) $ 会有3种值, 1 , -1 , 0 , 0对结果无影响,所以考虑如何让 $ \mu(\frac Td)!=0 $

若 $ \mu(\frac Td) =1 $ ,则$ \frac Td =1 $ ,所以 $ x_i=y_i $

若 $ \mu(\frac Td) =-1 $ ,则 $ x_i-y_i<=1 $ 且存在 $ x_i!=y_i $

所以,要使 $ F(T) !=0 $ ,必须满足 $ x_i-y_i<=1 $

设 $ a= \max_{i=1}^{k} x_i$,则 $ f(d) =a 或 a-1$

设D中一共有q个质因子的指数为a

分讨

1.q=k

(1)\(f(d)=a\):

\[\sum_{f(d)=a}\mu(\frac{T}{d})f(d)=a\times\sum_{f(d)=a}\mu(\frac{T}{d})=a\times\sum_{i=1}^k(-1)^{k-i}C_k^i=a\times (-1)^{k+1} \]

(2)\(f(d)=a-1\):

\[\sum_{f(d)=a-1}f(d)\mu(\frac{T}{d})=(a-1)\times\sum_{f(d)=a-1}\mu(\frac{T}{d})=(a-1)\times(-1)^k \]

所以,当q=k时

\[F(T)=a\times(-1)^{k+1}+(a-1)\times(-1)^k=(-1)^{k+1} \]

2.q<k

(1)\(f(d)=a\):

\[\sum_{f(d)=a}f(d)\mu(\frac{T}{d})=a\times\sum_{f(d)=a}\mu(\frac{T}{d})=a\times\sum_{i=1}^q(-1)^{q-i}C_q^i\times\sum_{j=0}^{k-q}(-1)^jC_{k-q}^j=0 \]

(2)\(f(d)=a-1\)

\[\sum_{f(d)=a-1}f(d)\mu(\frac{T}{d})=(a-1)\times\sum_{f(d)=a-1}\mu(\frac{T}{d})=(a-1)\times(-1)^q\times\sum_{j=0}^{k-q}(-1)^jC_{k-q}^j=0 \]

所以,当q<k时

\[F(T)=0 \]

F可以在线性筛的过程中求出,代码如下:

#include<bits/stdc++.h>
#define cc putchar(' ')
#define dd putchar('\n')
using namespace std;
const int N=1e7+10;
int pri[N],tot,vis[N],last[N],c[N],sum[N],T,n,m;
//c[i]代表i的最小素数的出现次数
//last[i]代表i的最小素数的c[i]次方
//sum[i]代表上述F(i)
int in(){
    int f=1,k=0;
    char c=getchar();
    while(c<'0'||c>'9')
    {
        if(c=='-')f=-1;
        c=getchar();
    }
    while(c>='0'&&c<='9')k=(k<<3)+(k<<1)+c-'0',c=getchar();
    return k*f;
}
void out(long long x){
    if(x<0) putchar('-'),x=-x;
    if(x<10) putchar(x+'0');
    else out(x/10),putchar(x%10+'0');
}
void init(){
    for(int i=2;i<=N-10;i++)
    {
        if(!vis[i])//若是素数
        {
            pri[++tot]=i;
            last[i]=i;//素数的最小素数就是自己
            c[i]=1;//只出现1次
            sum[i]=1;//因为是素数,所以满足条件1,此时k=1,(-1)^(k+1)=1
        }
        for(int j=1;j<=tot&&i*pri[j]<=N-10;j++)
        {
            int x=pri[j]*i;
            vis[x]=1;
            if(i%pri[j]==0)//若x已有素数pri[j]
            {
                last[x]=last[i]*pri[j];//因为只多了个pri[j],所以last[x]*pri[j]就行
                c[x]=c[i]+1;//pri[j]出现次数加1
                int t=x/last[x];//x去掉所有的pri[j]后剩下的值
                if(t==1) sum[x]=1;//若t=1,说明x只有pri[j]一个素数,计算可得为1
                else sum[x]=(c[x]==c[t]?-sum[t]:0);
                //判断x最小素数的出现次数是否与上t的最小素数出现次数相同,若相同则满足条件1,k+1,相当于
                //多乘一个-1,若不同则满足条件2,直接赋为0
                //sum[x]相当于递归求值,一直找t,一直往前递归,若一路上c[t]全部相同就乘-1,若有一个不同,
                //中间有了0,后面无论怎么乘都是0
                break;
            }
            last[x]=pri[j];//若没有素数pri[j],更新last,因为若有pri[j],就已经在上面跳过了
            c[x]=1;
            sum[x]=(c[i]==1?-sum[i]:0);//c[x]由c[i]转移,这个也是一个递归的过程,详细可见上文
        }
    }
    for(int i=2;i<=N-10;i++)
    sum[i]+=sum[i-1];//处理前缀和
}
long long work(int x,int y){//整除分块模板
    if(x>y) swap(x,y);
    long long ans=0;
    for(int l=1,r;l<=x;l=r+1)
    {
        r=min(x/(x/l),y/(y/l));
        ans+=1ll*(sum[r]-sum[l-1])*(x/l)*(y/l);
    }
    return ans;
}
signed main(){
    T=in();
    init();
    while(T--)
    {
        n=in(),m=in();
        out(work(n,m)),dd;
    }
    return 0;
}
///////////////////////////////////////////////////
//                      ♪♪♪                      //
///////////////////////////////////////////////////
posted @ 2025-08-15 14:16  why20031113  阅读(47)  评论(6)    收藏  举报