zoukankan      html  css  js  c++  java
  • hdu 5072 计数+容斥原理

    /*
    题意: 给出n个数(n<100000), 每个数都不大于100000,数字不会有重复。现在随意抽出3个,问三个彼此互质 或者 三个彼此不互质的数目有多少。
    思路: 这道题反着想,就是三个数中只有一对互质 或者只有两对互质的个数。  
    研究后发现 对于每个数字求出与其不互质的个数k   那么  sum ( k*(n-1-k) )/2 就是相反的数目, 所以最终的答案就是 C(n,3) -  sum ( k*(n-1-k) )/2.
    */
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    
    typedef __int64 LL;
    const int maxn=1000;
    int prime[maxn],flag[maxn],num;
    int numc[maxn*100+5],f[maxn*100+5];
    int factor[20],fac;
    LL sum;
    
    void getprimes()
    {
        memset(flag,1,sizeof(flag));
        int i,j;num=0;
        for(i=2;i<maxn;i++)
        {
            if(flag[i]) prime[num++]=i;
            for(j=0;j<num && prime[j]*i<maxn;j++)
            {
                flag[prime[j]*i]=0;
                if(i%prime[j]==0) break;
            }
        }
    }
    
    void dfs1(int now,int s)//找出它所有的因子
    {
        if(now==fac)
        {
            numc[s]++;
            return ;
        }
        dfs1(now+1,s);
        dfs1(now+1,s*factor[now]);
    }
    
    void dfs2(int id,int all,int now,int s )
    {
        if(now==all)
        {
            sum+=numc[s];
            return ;
        }
        if(id<fac)
        {
            dfs2(id+1,all,now+1,s*factor[id]);
            dfs2(id+1,all,now,s);
        }
    }
    
    void getfactors(int n)//分解质因子
    {
        int i;fac=0;
        for(i=0;i<num && prime[i]<=n;i++)
        {
            if(n%prime[i]==0)
            {
                factor[fac++]=prime[i];
                while(n%prime[i]==0) n/=prime[i];
            }
        }
        if(n>1) factor[fac++]=n;
    }
    
    int main()
    {
        getprimes();
        int t,n,i,j;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d",&n);
            memset(numc,0,sizeof(numc));
            for(i=1;i<=n;i++)
            {
                scanf("%d",f+i);
                getfactors(f[i]);
                dfs1(0,1);
            }
            LL ans=0;
            for(i=1;i<=n;i++)
            {
                getfactors(f[i]);
                LL ret=1,temp=0;
                for(j=1;j<=fac;j++)//容斥原理找出与它不互质的个数
                {
                    sum=0;
                    dfs2(0,j,0,1);
                    temp+=ret*sum;
                    ret=-ret;
                }
                if(temp==0) continue;//当f[i]==1时,所有数都与它不互质的是0个
                ans+=(temp-1)*(n-temp);
            }
            printf("%I64d
    ",(LL)n*(n-1)*(n-2)/6-ans/2);
        }
        return 0;
    }
  • 相关阅读:
    20145316《Java程序设计》第七周学习总结
    第三周博客问题总结
    20145316《Java程序设计》第六周学习总结
    20145316《Java程序设计》实验一:Java开发环境的熟悉(Windows + IDEA)
    八、九章知识点整理
    20145316许心远《Java程序设计》第5周学习总结
    第六章:继承与多态(知识梳理/查漏补缺)
    20145316许心远《Java程序设计》第4周学习总结
    实现最大索引堆
    Java排序算法全
  • 原文地址:https://www.cnblogs.com/xiong-/p/4127599.html
Copyright © 2011-2022 走看看