按位或

#include<iostream>
using namespace std;
int p[131072];
int mx = 131071;//二进制为17个1,题中范围内的数字,每位都是1
int q;
int main()
{
    /*对于每一次询问,我们肯定会选择所有y,满足y&x==y,即在二进制表达下,y是x的子集。
那么我们可以维护一个数组p[i],表示所有为i的子集的数字的Or值是多少。每次插入一个数字,如果它
没有重复出现过,就枚举它的超集更新答案。询问的时候只需要看p[x]是否等于x就好了。*/
    scanf("%d", &q);//几组数据
    while (q--)
    {
        int op, x; 
        scanf("%d%d", &op, &x);//op  1插入,2查询
        if (op == 1) 
        {
            if (p[x] == x) //此次插入数字已经存在,且插入0这里就终止了
                continue;
            int s = mx ^ x; //按位异或运算符,同0异1,相当于按位取反.
            for (int i = s; i; i = (i - 1) & s)//退出循环i==0.对插入的每一个数x,将二进制所有为1和x相同的记录
                p[i ^ x] |= x;
            p[x] = x;
        }
        else 
        {
            if (p[x] == x) 
                puts("YES");
            else 
                puts("NO");
        }
    }
    return 0;
}

全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务