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 mm with integer elements between 00 and 2n−12n−1 inclusive. Let's build an undirected graph on these integers in the following way: connect two integers xx and yy with an edge if and only if x&y=0x&y=0. Here && 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 nn and mm (0≤n≤220≤n≤22, 1≤m≤2n1≤m≤2n).
In the second line there are mm integers a1,a2,…,ama1,a2,…,am (0≤ai<2n0≤ai<2n) — the elements of the set. All aiai are 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:
Graph from second sample:
一个数A 按位取反为B 则 A & B = 0, B = 2 ^ n - A - 1
B的每一位1改为0不影响 A & B = 0
枚举A DFS给出的序列中是否存在 B 及 B改变后的数
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int mn = (1 << 22) + 10;
int n;
bool is[mn], vis[mn];
void dfs(int x)
{
if (vis[x])
return;
vis[x] = 1;
if (is[x]) // 将x包含进块 可以成为新的A DFS(B)
dfs((1 << n) - x - 1);
for (int i = 0; i < n; i++)
{
if (x & (1 << i)) // 修改 1 位成 0
dfs(x - (1 << i));
}
}
int main()
{
int m;
scanf("%d %d", &n, &m);
for (int i = 1; i <= m; i++)
{
int x;
cin >> x;
is[x] = 1;
}
int ans = 0;
for (int i = 0; i < 1 << n; i++)
{
if (!is[i] || vis[i]) // 已包含在其他块中
continue;
ans++;
vis[i] = 1; // 成为一块
dfs((1 << n) - i - 1);
}
printf("%d\n", ans);
return 0;
}