zoukankan      html  css  js  c++  java
  • POJ 3904

    第一道莫比乌斯反演的题。

    建议参看http://www.isnowfy.com/mobius-inversion/

    摘其中部分

    证明的话感觉写起来会比较诡异,大家意会吧
    说一下这个经典题目:令R(M,N)=1xM,1yN中 gcd(x,y)=1 的个数
    我们说G(z)表示gcd(x,y)是z的倍数的个数(以后都省略1xM,1yN的前提),换句话说z|gcd(x,y)的个数,那么很显然G(z)=M/zN/z,令F(z)表示gcd(x,y)=z的个数,

    所以G(z)=(F(z)+F(2z)+F(3z)...),于是我们得到F(z)=(G(z)μ(z)+G(2z)μ(2z)...),从而得到了我们最终的答案ans=z1M/zN/zμ(z)

    这里,只需要把z=1,通过求F(z)即可。

    上面之所以成立,因为莫比乌斯的另一种形式(我未找到,但确实成立)

    f(d) = ∑ g(n) (n % d == 0)

    g(d) = ∑  mu[n / d] * f(n) (n %d == 0)

    好像目前遇到的都是经典题目的类型了。。。

    给出求莫比乌斯函数的代码:

    void initial(){
    	int i,j;
    	for(i=1;i<N;i++) mobi[i]=1,vis[i]=false; 
    	for(i=2;i<N;i++) {
    		if(vis[i]) continue;
    		for(j=i;j<N;j+=i){
    			vis[j]=true;
    			if((j/i)%i==0){
    				mobi[j]=0; continue;
    			}
    			mobi[j]=-mobi[j];
    		}
    	}
    }
    

      

    POJ 代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define N 10005
    #define LL __int64
    using namespace std;
    
    int ID[N];
    int mobi[N],cnt[N];
    bool vis[N];
    LL myc[N];
    
    void initial(){
    	int i,j;
    	for(i=1;i<N;i++) mobi[i]=1,vis[i]=false; 
    	for(i=2;i<N;i++) {
    		if(vis[i]) continue;
    		for(j=i;j<N;j+=i){
    			vis[j]=true;
    			if((j/i)%i==0){
    				mobi[j]=0; continue;
    			}
    			mobi[j]=-mobi[j];
    		}
    	}
    	myc[0]=myc[1]=myc[2]=myc[3]=0;
    	myc[4]=1;
    	for(int i=5;i<N;i++)
    	myc[i]=myc[i-1]*(LL)i/(LL)(i-4);  //这里求的其实是组合数
    }
    
    int main(){
    	int n; int mx,tmp;
    	initial();
    	while(scanf("%d",&n)!=EOF){
    		mx=-1;
    		memset(ID,0,sizeof(ID));
    		for(int i=0;i<n;i++){
    			scanf("%d",&tmp);
    			ID[tmp]++;
    			mx=max(mx,tmp);
    		}
    		memset(cnt,0,sizeof(cnt));
    		for(int i=1;i<=N;i++){
    			for(int k=i;k<N;k+=i){
    				if(ID[k])
    				cnt[i]+=ID[k];
    			}
    		}
    		LL ans=0;
    		for(int i=1;i<=mx;i++){
    			ans=ans+(LL)mobi[i]*myc[cnt[i]];
    		}
    		printf("%I64d
    ",ans);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    Jessica's Reading Problem POJ
    FatMouse and Cheese HDU
    How many ways HDU
    Humble Numbers HDU
    Doing Homework again
    Stacks of Flapjacks UVA
    Party Games UVA
    24. 两两交换链表中的节点
    面试题 03.04. 化栈为队
    999. 可以被一步捕获的棋子数
  • 原文地址:https://www.cnblogs.com/jie-dcai/p/4004625.html
Copyright © 2011-2022 走看看