C. AND Graph+dfs

每次dfs尝试所有可能相连的状态
C. 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

with integer elements between 0 and 2n1 inclusive. Let's build an undirected graph on these integers in the following way: connect two integers x and y with an edge if and only if x&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 n

and m ( 0n22, 1m2n

).

In the second line there are m

integers a1,a2,,am ( 0ai<2n) — the elements of the set. All ai

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:

#include <bits/stdc++.h>


typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;

using namespace std;


/*
ll pw(ll a, ll b) {
	ll ans = 1; while (b) {
		while (!(b & 1)) b >>= 1, a = (a * a) % MOD;
		ans = (ans * a) % MOD, --b;
	} return ans;
}
*/

int msk;
int n, m;
int fl[1 << 22];
int was[1 << 22];

void dfs1(int v, int c) {
	if (c == 0) {
		fl[v] = 0;
		if (!was[msk - v])
			dfs1(msk - v, 1);
	}
	else {
		was[v] = 1;
		if (fl[v])
			dfs1(v, 0);
		for (int i = 0; i < n; ++i) {
			int x = v & (msk - (1 << i));
			if (!was[x])
				dfs1(x, 1);
		}
	}
}

int main() {
    freopen("in.txt","r",stdin);
	cin >> n >> m;
	msk = (1 << n) - 1;
	for (int i = 0; i < m; ++i) {
		int x;
		cin >> x;
		fl[x] = 1;
	}
	int ans = 0;
	for (int i = 0; i < (1 << 22); ++i) {
		if (fl[i]) {
			dfs1(i, 0), ++ans;
		}
	}
	cout << ans << "\n";
	return 0;
}

猜你喜欢

转载自blog.csdn.net/ujn20161222/article/details/80506503