[位运算] 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 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;
}

猜你喜欢

转载自blog.csdn.net/ummmmm/article/details/84330687