积性函数

67 阅读2分钟

莫比乌斯反演

莫比乌斯函数

定义: 将 xx 质因子分解分解 x=p1d1p2d2p3d3pkdkx=p_{1}^{d_{1}}p_{2}^{d_{2}}p_{3}^{d_{3}}···p_{k}^{d_{k}}.

μ(x)={0 di21x=1(1)k\mu (x)=\left\{ \begin{array}{rcl} 0 & & \exists \ d_{i}\ge 2\\ 1 & & x=1\\ (-1)^k & & \end{array} \right.

莫比乌斯函数筛法:

int pri[N],vis[N],Mobius[N],tot;
void sieve_Mobius(int x)
{
    vis[1]=Mobius[1]=1;
    for(register int i=2;i<=x;i++)
    {
        if(!vis[i])
        {
            pri[++tot]=i;
            Mobius[i]=-1;//质数只有一个质因子是他本身
        }
        for(register int j=1;j<=tot&&i*pri[j]<=x;j++)
        {
            vis[i*pri[j]]=1;
            if(!(i%pri[j]))
            {
                Mobius[i*pri[j]]=0;//i*pri[j]里至少包含两个pri[j]
                break;
            }
            Mobius[i*pri[j]]=-Mobius[i];//积性函数直接乘
        }
    }
}

性质1: 定义 S(x)=dnμ(d)S(x)=\sum_{d\mid n}^{}\mu (d),则有:

S(n)={1     n=10     n>1S(n)=\left\{\begin{matrix} 1\ \ \ \ \ n=1\\ 0\ \ \ \ \ n>1\\ \end{matrix}\right.

证明: n=1n=1 时,结论显然成立。

n=p1α1p2α2p3α3pkαkn=p_{1}^{\alpha_{1}}p_{2}^{\alpha_{2}}p_{3}^{\alpha_{3}}···p_{k}^{\alpha_{k}} , 在 n>1n>1 时,k1k\ge 1.

对于任意约数d=p1β1p2β2p3β3pkβkd=p_{1}^{\beta_{1}}p_{2}^{\beta_{2}}p_{3}^{\beta_{3}}···p_{k}^{\beta_{k}} , 0βiαi0\le\beta_{i}\le\alpha_{i}.

若存在 βi2\beta_{i}\ge 2 , 则有 μ(d)=0\mu(d)=0.

那么,若要使 μ(d)\mu(d)S(n)S(n) 产生影响 , 则需满足 βi[0,1]\forall \beta_{i}\in[0,1]

故, μ(d)\mu(d) 的取值取决于 βi=1\beta_{i}=1 的数量, 容易得到:

S(n)=i=0k(ki)(1)iS(n)=\sum_{i=0}^{k}\binom{k}{i}(-1)^i

由二项式定理可知:

(a+b)k=i=0k(ki)aibki(a+b)^k=\sum_{i=0}^{k}\binom{k}{i}a^{i}b^{k-i}

a=1 ,  b=1a=-1\ ,\ \ b=1 代入得:

0k=i=0k(ki)(1)i=S(n)0^k=\sum_{i=0}^{k}\binom{k}{i}(-1)^{i}=S(n)

证毕.

莫比乌斯反演

第一种形式

定义在正整数域的两个函数 F(n)F(n)f(n)f(n) , 若 F(n)=dnf(d)F(n)=\sum_{d\mid n}^{}f(d) ,

f(n)=dnμ(d)F(nd)f(n)=\sum_{d\mid n}{}\mu (d)F(\frac{n}{d}).

证明:

dnμ(d)F(nd)=dnμ(d)indf(i)=inf(i)dniμ(d)=inf(i)S(ni)       由上文可知,仅当i=nS(ni)=1,否则S(ni)=0=f(n)\begin{aligned} \sum_{d\mid n}{}\mu (d)F(\frac{n}{d})&=\sum_{d\mid n}{}\mu (d)\sum_{i\mid \frac{n}{d}}{}f(i)\\ &=\sum_{i\mid n}{}f(i)\sum_{d\mid \frac{n}{i}}{}\mu (d)\\ &=\sum_{i\mid n}{}f(i)S(\frac{n}{i})\ \ \ \ \ \ \ 由上文可知,仅当i=n时S(\frac{n}{i})=1,否则S(\frac{n}{i})=0\\ &= f(n) \end{aligned}

证毕.

第二种形式

F(n)=ndf(d)F(n)=\sum_{n \mid d}{}f(d) , 则 f(n)=ndμ(dn)F(d)f(n)=\sum_{n\mid d}{} \mu (\frac{d}{n})F(d). 证明:

ndμ(dn)F(d)=ndμ(dn)dif(i)=nidinμ(d)       设d=dn=niS(in)=f(n)\begin{aligned} \sum_{n\mid d}{} \mu (\frac{d}{n})F(d)&=\sum_{n\mid d}{}\mu (\frac{d}{n})\sum_{d\mid i}{}f(i)\\ &=\sum_{n\mid i}{}\sum_{d'\mid \frac{i}{n}}{}\mu (d') \ \ \ \ \ \ \ 设d'=\frac{d}{n}\\ &= \sum_{n\mid i}{}S(\frac{i}{n})\\ &=f(n) \end{aligned}

证毕.

problem b

题解:设 F(k)=x=1ay=1b[k(x,y)]=akbk      f(k)=x=1ay=1b[k=(x,y)]F(k)=\sum_{x=1}^{a}\sum_{y=1}^{b}\left [ k \mid (x,y) \right ]=\lfloor\frac{a}{k}\rfloor\lfloor\frac{b}{k}\rfloor\ \ \ \ \ \ f(k)=\sum_{x=1}^{a}\sum_{y=1}^{b}\left [ k = (x,y) \right ]

则有

F(k)=kdf(d)F(k)=\sum_{k\mid d}{}f(d)

由莫比乌斯反演定律可知:

f(k)=kdμ(dk)F(d)=kdμ(dk)adbd=dμ(d)adbd     设d=dk,a=ak,b=bk.\begin{aligned} f(k)&=\sum_{k\mid d}{}\mu(\frac{d}{k})F(d)\\ &=\sum_{k\mid d}{}\mu(\frac{d}{k})\lfloor\frac{a}{d}\rfloor\lfloor\frac{b}{d}\rfloor\\ &=\sum_{d'}{}\mu(d')\lfloor\frac{a'}{d'}\rfloor\lfloor\frac{b'}{d'}\rfloor\ \ \ \ \ 设d'=\frac{d}{k},a'=\frac{a}{k},b'=\frac{b}{k}. \end{aligned}

等式右边 adbd\lfloor\frac{a'}{d'}\rfloor\lfloor\frac{b'}{d'}\rfloor 可用整除分块计算。

#include<bits/stdc++.h>
#define N 100005
#define LL long long 
using namespace std;

int t;
LL a,b,c,d,k;

inline int qr()//快读
{
    int x=0,w=1;char ch=0;
    while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
    return x*w;
}

//分别表示,质数数组,是否访问过,莫比乌斯函数,莫比乌斯函数前缀和,素数个数
int pri[N],vis[N],mobius[N],sum[N],tot;

void sieve(int x)//莫比乌斯筛法模板
{
    mobius[1]=vis[1]=1;
    for(register int i=2;i<=x;i++)
    {
        if(!vis[i])
        {
            pri[++tot]=i;
            mobius[i]=-1;
        }
        for(register int j=1;j<=tot&&i*pri[j]<=x;j++)
        {
            vis[i*pri[j]]=1;
            if(!(i%pri[j]))
            {
                mobius[i*pri[j]]=0;
                break;
            }
            mobius[i*pri[j]]=-mobius[i];
        }
    }
    for(register int i=1;i<=x;i++)
        sum[i]=sum[i-1]+mobius[i];
}

//整除分块
inline LL f(int a,int b)
{
    LL res=0;
    a=a/k,b=b/k;
    int n=min(a,b);
    int l=1,r=0;
    while(l<=n)
    {
        r=min(n,min(a/(a/l),b/(b/l)));
        res+=(LL)(sum[r]-sum[l-1])*(a/l)*(b/l);
        l=r+1;
    }
    return res;
}

int main()
{
    //freopen("data.in","r",stdin);
    //freopen("data.out","w",stdout);
    sieve(50005);
    t=qr();
    while(t--)
    {
        a=qr();b=qr();c=qr();d=qr();k=qr();
        printf("%lld\n",f(b,d)-f(a-1,d)-f(b,c-1)+f(a-1,c-1));
    }
    //system("pause");
    return 0;
}