1364 字
5 分钟阅读
隐匿社交网络 / NC287758
原题链接:https://ac.nowcoder.com/acm/problem/287758
牛客网有一个名为牛爱网神秘的入口。这天,牛可乐正在策划牛爱网的全新社交活动。
每个人的账号在初始时都会被分配一个权重,第 i 个账号的权重为 w_i 。对于任意的两个账号 i 和 j ,如果权重满足 ( w_i and w_j \ge 1 ) ,那么就会被分配到同一个社交网络。
现在,牛可乐已经为 n 个账号分配了权重,他想知道,包含账号数量最多的社交网络中,包含多少个账号。
牛爱网的日常维护工作忙坏了牛可乐,请你帮帮他。
其中, and 表示按位与运算。
思路: 将每一个二进制位第一次出现1的权重用map存起来,每有权重这个二进制位是1,就用并查集合并两个账号,最终枚举所有集合中账号数最多的即可。
我的AC代码:
#include <bits/stdc++.h>
#define all(a) (a).begin(),(a).end()
using namespace std;
using ll = long long;
using ull = unsigned long long;
const int N = 1e5 + 50;
vector<int> dsu (N,0);
vector<int> mysize (N,0);
void init(int n){
for(int i = 1;i <= n;i++){
dsu[i] = i;
mysize[i] = 1;
}
}
int find(int n){
queue<int> q;
while(dsu[n] != n){
q.push(n);
n = dsu[n];
}
while(!q.empty()){
dsu[q.front()] = n;
q.pop();
}
return n;
}
void uni(int a,int b){
int fa = find(a);
int fb = find(b);
if(fa != fb){
dsu[fa] = fb;
mysize[fb] += mysize[fa];
mysize[fa] = 0;
}
}
void solve(){
int n;
cin >> n;
dsu = vector<int> (N,0);
mysize = vector<int> (N,0);
init(n);
unordered_map<int,int> mp;
for(int i = 1;i <= n;i++){
ll x;
cin >> x;
ll tmp = x;
int cnt = 0;
while(tmp > 0){
if(tmp & 1){
if(mp.find(cnt) != mp.end()){
uni(mp[cnt],i);
}else{
mp[cnt] = i;
}
}
cnt++;
tmp >>= 1;
}
}
cout << *max_element(all(mysize)) << "\n";
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t = 1;
cin >> t;
while(t--){
solve();
}
return 0;
}
