题解 | 隐匿社交网络

隐匿社交网络

https://www.nowcoder.com/practice/2870f9db6aeb4eb08fbd6460397f9bf4

按位与操作,同时是 1 才会是 1,数据两两做与操作会超时。
所以可以先考虑吧每个数转为其二进制形式存储起来,一个数的二进制形式存一行,n个数,总共n行。时间复杂度为:nlogn
遍历每一列,把是 1 的每一行下标用并查集合并,因为它们做与操作结果会大于等于 1
并查集,p[N], si[N],p 维护集合,si 维护集合中的个数。

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+6;
int ejz[N][1000];
long long arr[N];
int T;
int p[N],si[N];
int find(int a){
    if(p[a]!=a){
        int pa=find(p[a]);
        p[a]=pa;
    }
    return p[a];
}
void merge(int a,int b){
    int pa=find(a),pb=find(b);
    if(pa!=pb){
        p[pa]=pb;
        si[pb]+=si[pa];
    }
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr), cout.tie(nullptr);
    cin>>T;
    while(T--){
        int n,ma_idx=0;
        cin>>n;
        for(int i=0;i<n;i++){
            fill(ejz[i],ejz[i]+1000,0);
        }
        for(int i=0;i<n;i++){
            cin>>arr[i];
            long long x=arr[i];
            int idx=0;
            while(x){
                ejz[i][idx]=x%2;
                idx++;
                x/=2;
            }
            ma_idx=max(ma_idx,idx);
        }
        for(int i=0;i<n;i++){
            p[i]=i, si[i]=1;
        }
        for(int i=0;i<ma_idx;i++){
            int j=0;
            while(j<n && ejz[j][i]==0) j++;
            // j=find(j);
            for(int k=j+1;k<n;k++){
                if(ejz[k][i]==1){
                    merge(k,j);
                }
            }
        }
        // for(int i=0;i<n;i++){
        //     cout<<p[i]<<" ";
        // }
        // cout<<endl;
        int ans=1;
        for(int i=0;i<n;i++){
            ans=max(ans,si[i]);
        }
        cout<<ans<<endl;
    }
    return 0;
}

全部评论

相关推荐

04-02 16:49
门头沟学院 Java
_bloodstream_:我也面了科大讯飞,主管面的时候听说急招人优先考虑能尽快实习的,我说忙毕设,后面就一直没消息了
点赞 评论 收藏
分享
评论
3
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务