• yzoj2057 x 题解


    题意:给出一个集合,要求把这个集合分成两部分,使得一个集合中的任一元素都与另一个集合的全部元素都两两互质

    暴力

    枚举每个元素O(n^2)再暴力判gcd=1,如果非1就放入不同集合内,用并查集维护联通块的个数即可,答案就是联通块个数减2(无空集)

    考虑在暴力的基础上优化,我们可以发现一个元素与它的质因数的倍数一定不在同一集合内,我们可以枚举它的质因数,将它的倍数和它划分于用并查集连接,这样就形成了若干联通块,质数可先用线性筛预处理,注意一下1的判断即可。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int mod=1e9+7,MAX=1e6+10; 
    int T;
    long long ans,n,a[MAX],v[MAX],p[MAX],fa[MAX],cnt=0,maxn=-1,book[MAX],sum;
    void prime(){
        for(int i=2;i<=MAX;++i){
            if(!v[i]){
                p[++cnt]=i;
                for(int j=i;j<=MAX/i;++j) v[i*j]=1;
            }  
        }
    }
    long long find(long long x){
        if(fa[x]==x) return x;
        return fa[x]=find(fa[x]);
    }
    long long clu(long long x,long long y){
        long long tmp=1;
        while(y){
            if(y&1) tmp=(tmp*x)%mod;
            x=(x*x)%mod;
            y=y>>1;
        }
        return tmp%mod;
    }
    int main(){
    	prime();
        scanf("%d",&T);
        while(T--){
            scanf("%lld",&n);
            memset(a,0,sizeof(a));
            memset(book,0,sizeof(book));
            memset(v,0,sizeof(v));
            ans=0,maxn=-1,sum=0;
            for(int i=1;i<=MAX;++i) fa[i]=i;
            for(int i=1;i<=n;++i){
                scanf("%lld",&a[i]);
                maxn=max(maxn,a[i]);
                if(a[i]==1) sum++;
                v[a[i]]++;
            }
            for(int i=1;i<=cnt;++i){
                for(int j=1;j*p[i]<=maxn;++j){
                    if(v[j*p[i]]){
                        long long fax=find(p[i]);
                        long long fbx=find(j*p[i]);
                        if(fax!=fbx) fa[fax]=fbx;
                    }
                }
            }
            for(int i=1;i<=n;++i){
                if(!book[find(a[i])]) ans++,book[find(a[i])]=1;
            }
            if(sum>1) ans+=(sum-1);
            ans=clu(2,ans);
            ans=(ans-2+mod)%mod;
            printf("%d
    ",ans);
        }
    	return 0;
    }
    
  • 相关阅读:
    [LuoguP2161] 会场预约
    [LuoguP1198] 最大数
    [LuoguP1484] 种树
    [LuoguP1801] 黑匣子
    [LuoguP1196]银河英雄传说
    [LuoguP1345] 奶牛的电信Telecowmunication
    [LuoguP1119]灾后重建
    【笔记】一元函数微分学
    【复习】Listening and Reading Comprehension
    【笔记】一元函数的不定积分
  • 原文地址:https://www.cnblogs.com/donkey2603089141/p/11414774.html
Copyright © 2020-2023  润新知