按位与操作,同时是 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;
}