题目链接:F. AND Graph
题解:一个数x&~x==0;~x=(1<<n)-1-x;然后对与x任意一个0位取反之后的得到数y,然后~y同样可以与x相连。所以每次从一个未标记的的数开始标记与它相连的数。看有多少个连通块。
#include<bits/stdc++.h> #include <iostream> #include <string.h> #include <algorithm> #include <stdio.h> #include <math.h> #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 #define ll long long #define pb push_back #define mem(a, b) memset(a, b, sizeof(a)) const ll inf=0x3f3f3f3f3f3f; using namespace std; const int maxn=1e6+6; typedef pair<int,int> P; int m,n,s,k; bool vis[(1<<22)+10][2]; bool yu[(1<<22)+10]; int a[(1<<22)+10]; void dfs(int x,int y) { if(vis[x][y])return; vis[x][y]=true; if(y==0)dfs(x,1); else { for(int i=0;i<n;i++) { if(!(x&(1<<i))) { dfs(x^(1<<i),1); } } if(yu[(1<<n)-1-x])dfs((1<<n)-1-x,0); } } int main() { ios::sync_with_stdio(false);cin.tie(0); cin>>n>>m; for(int i=0;i<m;i++) { cin>>a[i];yu[a[i]]=true; } int ans=0; for(int i=0;i<m;i++) { if(!vis[a[i]][0]) { dfs(a[i],0); ans++; } } cout<<ans<<endl; return 0; }