#include <iostream>
#include <vector>
using namespace std;
#define int long long
const int N = 100010;
int w[N],s[N];
int fa[N];
int find(int x){
if(x!=fa[x]){
int t = fa[x];
fa[x] = find(fa[x]);
}
return fa[x];
}
void merge(int x,int y){
x = find(x);
y = find(y);
if(x!=y){
fa[x] = y;
s[y]+=s[x];
}
}
void solve(){
int n;cin>>n;
int res = 1;
for(int i = 1;i<=n;i++){
cin>>w[i];
fa[i] = i;
s[i] = 1;
}
vector<int>pre;
for(int k = 0;k<=60;k++){
for(int i = 1;i<=n;i++){
if((w[i]>>k)&1){
pre.push_back(i);
}
}
for(int i = 0;i<pre.size();i++){
merge(pre[0], pre[i]);
}
pre.clear();
}
for(int i = 1;i<=n;i++){
res = max(res,s[i]);
}
cout<<res<<'\n';
}
signed main() {
int t = 1;cin>>t;
while(t--){
solve();
}
return 0;
}
// 64 位输出请用 printf("%lld")
看了大佬的解法
- 我们需要将账号分成多个社交网络,其中两个账号属于同一网络当且仅当它们的权重按位与结果至少为1这实际上意味着两个账号至少有一个相同的二进制位为1直接统计每个二进制位的出现次数并不能完全反映社交网络的结构,因为账号可能通过多个不同的二进制位间接连接
- 账号之间的连接关系具有传递性:如果账号A和B有共同位,B和C有共同位,那么A、B、C属于同一网络因此需要使用并查集来维护连通分量
- 使用并查集来维护账号的连通性对于每个二进制位,将该位上为1的所有账号合并最后统计最大的连通分量大小。



京公网安备 11010502036488号