• 莫比乌斯反演略解


    莫比乌斯反演,又称懵逼钨丝繁衍

    一、莫比乌斯函数

    学莫比乌斯反演之前要学一下莫比乌斯函数

    设正整数N珂以分解质因数成(N=p_1^{c_1}p_2^{c_2}…p_m^{c_m})

    定义莫比乌斯函数,记做(mu(N))

    [ mu(x) = left{ egin{aligned} 0 qquad qquad qquad qquad exists i in [1,m] , c_i>1\ 1 qquad m equiv 0 (mod 2) , forall i in [1,m] , c_i=1 \ -1 qquad m equiv 1 (mod 2) , forall i in [1,m] , c_i=1 end{aligned} ight. ]

    通俗的讲,当N包含相等的质因子时,(mu (N)=0)。当N的所有质因子各不相等时,若N有偶数个质因子,(mu (N)=1),若N有奇数个质因子(mu (N)=-1)

    下面我们来讲讲如何求莫比乌斯函数

    当只需要求一项莫比乌斯函数时,则珂以用分解质因数(试除法或pollard's Rho)

    若求1~N的每一项的莫比乌斯函数,我们珂以用筛法来计算(还在上面那篇文章中)。先把所有的(mu)值初始化为1.接下来,对于筛出的每一个质数p,令(mu (p) = -1),并扫描p的倍数(x=2p,3p,…,lfloor n/p floor *p),检查x能否被(p^2)整除。若能,则令(mu (x) = 0),否则令(mu (x) = -mu (x))

    for(register int i=1;i<=n;++i)
    	miu[i]=1,v[i]=0;
    for(register int i=2;i<=n;++i)
    {
    	if(v[i])
    		continue;
    	miu[i]=-1;
    	for(register int j=i<<1;j<=n;j+=i)
    	{
    		v[j]=1;
    		if((j/i)%i==0)
    			miu[j]=0;
    		else
    			miu[j]*=-1;
    	}
    }
    

    2、莫比乌斯反演公式

    莫比乌斯反演分为两种形式

    形式1:

    若函数F(x)和f(x)满足

    $$F(n)=sum_{d|n}f(d)$$

    那么就有

    $$f(n)=sum_{d|n}mu(d)F(frac{n}{d})$$

    形式2:

    若函数F(x)和f(x)满足

    $$F(n)=sum_{n|d}f(d)$$

    那么就有

    $$f(n)=sum_{n|d}mu(frac{d}{n})F(d)$$

    两条性质

    我们需要运用这两条性质来证明莫比乌斯反演

    性质1:

    对于任何正整数n有

    $$ sum_{d|n}mu(d) = left{

    egin{aligned}
    1 qquad (n=1)
    0 qquad (n>1)
    end{aligned}
    ight.

    [ #### 证明: ##### 1.当n=1时显然成立 ##### 2、在n>1时,珂以讲n分解成$n=p_1^{c_1}p_2^{c_2}…p_m^{c_m}$ ##### 在n的所有因子中,$mu$的值不为零的只有所有质因子次数为都1的因子,其中质因数个数为r个的因子有$C_m^r$个 ##### 那么显然有: ##### $$sum_{d|n}mu(d)=C_m^0-C_m^1+C_m^2+…+(-1)^mC_m^m=sum_{i=0}^m(-1)^iC_m^i]

    所以我们要证明(sum_{i=0}^m(-1)^iC_m^i)
    根据二项式定理:
    $$(x+y)^n=sum_{i=0}^nC_n^ix^iy^{n-i}$$
    将x=1,y=-1带入即珂以得证

    性质2:

    $$sum_{d|n}frac{mu(d)}{d}=frac{varphi(n)}{n}$$

    证明珂以直接带入反演公式

    莫比乌斯反演证明

    懒着写了

    莫比乌斯反演的应用

    讲了那么多,最后也只是记住形式

    所以我们结合Luogu P3455 [POI2007]ZAP-Queries来讲一下莫比乌斯反演的应用

    题目大意:求对于区间([1,a])内的整数x和([1,b])内的y,满足(gcd(x,y)=d)的数对的个数

    设F(t)表示满足gcd(x,y)%t=0的数对个数,f(t)表示满足(gcd(x,y)=t)的数对个数,实际上答案就是f(d)

    这就满足莫比乌斯反演的关系式了

    显然我们珂以得知(F(t)=(b/t)*(d/t))

    我们根据反演的第二个公式便珂以得出

    $$f(d)=sum_{n|d}mu(frac{d}{n})F(d)$$

    还有一个叫整除分块的小技巧

    大体长这样

    for(register int l=1,r;l<=n;l=r+1)
    {
        r=n/(n/l);
        ans+=(r-l+1)*(n/l);
    }
    

    就这样就过了qaq

    #include <bits/stdc++.h>
    #define N 50005
    #define ll long long 
    #define getchar nc
    using namespace std;
    inline char nc(){
        static char buf[100000],*p1=buf,*p2=buf; 
        return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++; 
    }
    inline int read()
    {
        register int x=0,f=1;register char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
        return x*f;
    }
    inline void write(register ll x)
    {
        if(!x)putchar('0');if(x<0)x=-x,putchar('-');
        static int sta[30];register int tot=0;
        while(x)sta[tot++]=x%10,x/=10;
        while(tot)putchar(sta[--tot]+48);
    }
    inline int Min(register int x,register int y)
    {
    	return x<y?x:y;
    }
    int v[N],miu[N],sum[N];
    int main()
    {
    	for(register int i=1;i<=N;++i)
    		miu[i]=1,v[i]=0;
    	for(register int i=2;i<=N;++i)
    	{
    		if(v[i])
    			continue;
    		miu[i]=-1;
    		for(register int j=i<<1;j<=N;j+=i)
    		{
    			v[j]=1;
    			if((j/i)%i==0)
    				miu[j]=0;
    			else
    				miu[j]*=-1;
    		}
    	}
    	for(register int i=1;i<=N;++i)
    		sum[i]=sum[i-1]+miu[i];
    	int t=read();
    	while(t--)
    	{
    		int a=read(),b=read(),d=read();
    		int maxround=Min(a/d,b/d);
    		ll ans=0;
    		for(register int l=1,r;l<=maxround;l=r+1)
    		{
    			r=Min((a/d)/((a/d)/l),(b/d)/((b/d)/l));
    			ans+=(ll)((a/d)/l)*((b/d)/l)*(sum[r]-sum[l-1]);	
    		}	
    		write(ans),puts("");
    	}
    	return 0;
    }
    
  • 相关阅读:
    wireshark筛选器汇总
    .net中的"异步"-手把手带你体验
    Javascript手记-垃圾收集
    Sqlserver作业-手把手带你体验
    oracle11g重置system密码,外二
    return Acad::ErrorStatus::eOk引发error C2220: warning treated as error
    RegOpenKeyEx和RegSetValueEx返回ERROR_SUCCESS,但注册表未发生变化。
    windows7 阻止copyfile到windows目录的解决办法
    如何让AutoCAD自动加载Arx,比如ArxDbg.arx
    入口点函数的19种消息,AcRxArxApp只处理16种。
  • 原文地址:https://www.cnblogs.com/yzhang-rp-inf/p/10124488.html
Copyright © 2020-2023  润新知