POJ -- 2443 Set Operation 【 二进制压位 】

来源:互联网 发布:淘宝网代理加盟 编辑:程序博客网 时间:2024/05/22 03:28

传送门
题意应该好懂, 就不说了.
思路:将每一个集合看成是一行,也成了一个10000 * 1000 的0、1矩阵,对于每个数来书,它所在的列的0、1分布情况也就是它所在集合的情况。但问题是现在一共有1000行,2^1000肯定不行,但考虑到一个int可以存32位(2^32),1000<32*32,所以可以开32个整数,每个整数的二进制的每一位代表每一行,这样就可以在q*32的可接受的时间复杂度内查询出结果。将扫描1000变为扫描32,利用整数的位操作减少为1/32.
//然后为了直观方便的给出, 所以我用的bitset.
AC Code

/** @Cain*/#include<bitset>const int maxn = 1e4+5;void solve(){    int n;    scanf("%d",&n);    bitset<1005> bit[maxn];  //1005代表那些集合, maxn代表那些数的范围,    //bit[3][5] = 1 说明第5个集合有3这个数.    for(int i=1;i<=n;i++){        int k; scanf("%d",&k);        while(k--){            int u; scanf("%d",&u);            bit[u][i] = 1;        }    }    int q;    scanf("%d",&q);    while(q--){        int u,v;        scanf("%d%d",&u,&v);        bitset<1005> tmp;   //自动初始化为0.        if((bit[u] & bit[v]) == tmp){   // & 的优先级比== 更低.            //如果等于0,就是说明没有在任何一个集合中有相同的元素.            printf("No\n");        }        else            printf("Yes\n");    }}int main(){    int t = 1;    //cin >> t;    while(t--){        solve();    }}
原创粉丝点击