zoukankan      html  css  js  c++  java
  • 【Learning】 莫比乌斯反演

    莫比乌斯反演

    ​ 对于两个定义域为非负整数的函数(F(n))(f(n))

    ​ 若满足:(F(n)=sumlimits_{d|n}f(d)),则反演得到(f(n)=sumlimits_{d|n}mu(d)F(frac n d))

    [sum_{dmid n}mu(d)F(frac n d)= sum_{dmid n}mu(d)sum_{d'mid (n/d)}f(d')= sum_{d'mid n}f(d')sum_{d|(n/d')}mu(d)\ ecause根据下文mu的性质,当且仅当n/d'=1时式子有值,此时d'=n,d=1\ herefore原式=f(n)*mu(1)=f(n) ]

    ​ 常用变式:若满足:(F(n)=sumlimits_{n|d}f(d)),则反演得到(f(n)=sumlimits_{n|d}mu(frac d n)F(d))

    (mu(i))函数(莫比乌斯函数)

    ​ 定义:

    [mu(d)=egin{cases} 1& d=1\ (-1)^k& d=p_1p_2...p_k&(p_i为互异素数)\ 0& d=p_1p_2...p_k &(p_i为素数,但有重复,即存在平方因子) end{cases} dinmathbb{N}^* ]

    ​ 按照定义用线性筛来求解:

    ​ 循环(i),判定(i)为素数时,令(mu(i)=-1)

    ​ 筛到(x)时((x=i*p)),若(i|p),则(x)(p^2)这个因子,此时令(mu(x)=0)

    ​ 否则(i mid p),则(x)的互异素数数量加1,则令(mu(x)=-mu(i))

    mu[1]=1;
    for(int i=2;i<=n;i++){
    	if(!vis[i]){
    		lis[++cnt]=i;
    		mu[i]=-1;
    	}
    	for(int j=1;j<=cnt&&i*lis[j]<=n;j++){
    		vis[i*lis[j]]=1;
    		if(i%lis[j]==0){
    			mu[i*lis[j]]=0;
    			break;
    		}
    		mu[i*lis[j]]=-mu[i];
    	}
    }
    

    (mu(i))函数性质:(1)它是积性函数。

    ​ (2)对于(ninmathbb{N}^*)

    [sum_{dmid n}mu(d)=egin{cases} 1& n=1\ 0& else end{cases} ]

    [sum_{d|n}frac{mu(d)}{d}=frac{phi(n)}{n} ]

    求解应用

    BZOJ2820 GCD

    ​ 给定(n,m),求满足(1le xle n,1le yle m)(gcd(x,y))为质数的((x,y))有多少对.

    ​ 我们设出两个函数,使得它们满足反演变式的关系:(F(d))表示(dmid gcd(x,y)) 的有多少对,(f(d)) 表示(gcd(x,y)=d)的有多少对,其中(1le xle n,1le yle m).

    ​ 它们确实满足(F(n)=sumlimits_{n|d}f(d)) . 故(f(n)=sumlimits_{n|d}mu(frac d n)F(d)). 方便的是$$F(d)=lfloor frac n d floorlfloorfrac m d floor $$,即每个数对可以看成((d*x,d*y)),然后考虑(x)(y)的取值各有多少种,乘起来便是(F(d)) ,因此(f(n)=sumlimits_{nmid d }mu(frac d n)lfloor frac n d floorlfloorfrac m d floor).

    [egin{aligned} ans&=sum_{p}f(p)\ &=sum_{p}sum_{pmid d }mu(frac d p)lfloor frac n d floorlfloorfrac m d floor\ &=sum_psum_{k=1}^{lfloor min(n,m)/p floor}mu(frac{kp}p)lfloorfrac n {kp} floorlfloorfrac m {kp} floor&枚举d的取值,用kp替代\ &=sum_{T=1}^{min(n,m)}lfloorfrac n T floorlfloorfrac m T floorsum_{pmid T}mu(frac T p) &令T=kp end{aligned} ]

    ​ 令(g(x)=sum_limits{pmid x}mu(frac x p)) ,那么现在的任务是求出所有的(g(x)). 考虑用线性筛的方式来求:

    ​ 循环(i), 判定(i)是质数时,令(g(i)=mu(1)=1)

    ​ 筛到(x)时((x=i*P)),若(Pmid i),则(x)(P^2)这个因子,除非求值式中的(p)(x)中的(P^2)除去,否则(mu(frac x p)=0),唯一一个有值的是当(p=P)(mu(frac x P)=mu(i)). 综合,(g(x)=mu(i))

    ​ 若(P mid i),则(P)(i)互质。当(p=P)时,值是(mu(frac {iP}P)=mu(i))

    ​ 当(p e P)时,循环的(p)和g(i)中循环的(p)是一样的 ,则$$且sum_{p|x且p!=P}mu(frac xp)=sum_{p|i}mu(frac i pP)=sum_{p|i}mu(frac i p)mu(P)=mu(P)sum_{p|i}mu(frac ip)=-1g(i)=-g(i)$$

    ​ 综合,(g(x)=mu(i)-f(i))

    ​ 于是用线性筛求出了(g(x))

    ​ 回到答案的表达式(ans=sumlimits_{T=1}^{min(n,m)}lfloorfrac n T floorlfloorfrac m T floorsum_{pmid T}mu(frac T p)),如果循环(1...min(n,m))显然不够快,考虑(lfloorfrac n T floorlfloorfrac m T floor)的取值是根号级别的,对于每一组(lfloorfrac n T floorlfloorfrac m T floor)相等的(lleq Tleq r),可以加快计算,将(lfloorfrac n T floorlfloorfrac m T floor)提取出来,那么这些(T)的贡献就是(lfloorfrac n T floorlfloorfrac m T floorsumlimits_{i=l}^rg(i)),预处理出(g(i))的前缀和即可。

    #include <cstdio>
    using namespace std;
    const int N=10000001;
    typedef long long ll;
    int T,n,m;
    int mu[N],g[N];
    int vis[N],lis[N],cnt;
    inline void swap(int &x,int &y){int t=x;x=y;y=t;}
    inline int min(int x,int y){return x<y?x:y;}
    int main(){
    	freopen("input.in","r",stdin);
    	mu[1]=1;
    	for(int i=2;i<N;i++){
    		if(!vis[i]){
    			lis[++cnt]=i;
    			mu[i]=-1;
    			g[i]=1;
    		}
    		for(int j=1;j<=cnt&&i*lis[j]<N;j++){
    			int p=lis[j],x=i*p;
    			vis[x]=1;
    			if(i%lis[j]==0){
    				mu[x]=0;
    				g[x]=mu[i];
    				break;
    			}
    			else{
    				mu[x]=-mu[i];
    				g[x]=mu[i]-g[i];
    			}
    		}
    	}
    	for(int i=1;i<N;i++) g[i]+=g[i-1];
    	scanf("%d",&T);
    	while(T--){
    		scanf("%d%d",&n,&m);
    		if(n>m) swap(n,m);
    		ll ans=0;
    		for(int i=1,j;i<=n;i=j+1){
    			j=min(n/(n/i),m/(m/i));
    			ans+=1LL*(n/i)*(m/i)*(g[j]-g[i-1]);
    		}
    		printf("%lld
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    JavaWeb--HttpSession案例
    codeforces B. Balls Game 解题报告
    hdu 1711 Number Sequence 解题报告
    codeforces B. Online Meeting 解题报告
    ZOJ 3706 Break Standard Weight 解题报告
    codeforces C. Magic Formulas 解题报告
    codeforces B. Sereja and Mirroring 解题报告
    zoj 1109 Language of FatMouse 解题报告
    hdu 1361.Parencodings 解题报告
    hdu 1004 Let the Balloon Rise 解题报告
  • 原文地址:https://www.cnblogs.com/RogerDTZ/p/8214141.html
Copyright © 2011-2022 走看看