题目链接:
http://codeforces.com/contest/987/problem/F
F. AND Graph
time limit per test
4 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
You are given a set of size m
is the bitwise AND operation. Count the number of connected components in that graph.
Input
In the first line of input there are two integers n
).
In the second line there are m
integers a1,a2,…,am ( 0≤ai<2n) — the elements of the set. All aiare distinct.
Output
Print the number of connected components.
Examples
Input
Copy
2 3 1 2 3
Output
Copy
2
Input
Copy
5 5 5 19 10 20 12
Output
Copy
2
Note
Graph from first sample:
扫描二维码关注公众号,回复:
2239800 查看本文章
Graph from second sample:
题意:给你一个n,一个m,m < 2^n, 然后就是如果 x & y == 0 的话就可以将这2个数连起来, 求最后的有几块。
题解: 不难想到,x有边连出的一定是 (2^n-1) ^ x 的一个子集,直接连子集复杂度是爆炸的。。。但是我们可以一个1一个1的消去,最后变成补集的一个子集。
但是必须当且仅当 至少有一个 a 等于 x 的时候, 可以直接dfs(all ^ x) ,否则直接消1连边。。。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1<<22;
int n, m, a[maxn], all;
int vis[maxn];
int have[maxn];
void dfs(int x)
{
if(vis[x]) return;
vis[x] = 1;
if(have[x]) dfs(all ^ x);
for(int i = 0;i < n;i ++) {
if(x & 1 << i) dfs(x ^ 1 << i);
}
}
int main()
{
ios::sync_with_stdio(false), cin.tie(0);
cin >> n >> m;
for(int i = 1;i <= m;i ++) cin >> a[i];
for(int i = 1;i <= m;i ++) have[a[i]] = 1;
all = 1<<n;
all--;
int res = 0;
for(int i = 1;i <= m;i ++) {
if(!vis[a[i]]) {
vis[a[i]] = 1;
res ++;
dfs(all ^ a[i]);
}
}
cout << res << '\n';
return 0;
}