[位運算] F. AND Graph CF987F
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
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; }