题解 | 隐匿社交网络
隐匿社交网络
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; }