因为权重在18次方以内,变为2进制不超过64位,最多情况下只有64个网络,从左到右针对每一个数字,可以通过遍历网络,来看自己是否属于某一个网络。
网络的标志为:网络内各个数字的或,如果这个位置上为1,说明网络内至少存在一个用户,在这个位置上为1。
判断一个数字是否属于一个网络:这个数字和网络标识与,如果与的结果大于等于1,则是属于这个网络的。
如果当前遍历的这个数字可以属于多个网络,那么这几个网络是可以通过这个数字连接成为一个网络,将其合并就可以了。类似于并查集的思想。
#include <bits/stdc++.h> using namespace std; void solve() { int n; cin >> n; vector<long long> a(n); for (int i = 0; i < n; i++) cin >> a[i]; map<long long, int> m; int ans = 0; for (int i = 0; i < n; i++) { vector<long long> ks; for (auto [k, v] : m) { if ((a[i] & k) >= 1) { ks.push_back(k); } } long long kk = a[i]; int cnt = 0; for (long long k : ks) { kk |= k; cnt += m[k]; m.erase(k); } m[kk] = cnt + 1; ans = max(ans, cnt + 1); } cout << ans << "\n"; } int main() { int n; cin >> n; while (n--) { solve(); } }