zoukankan      html  css  js  c++  java
  • NOIP模拟-----位运算

    题目

    有q次操作,每次操作是以下两种:
    1、 加入一个数到集合中
    2、 查询,查询当前数字与集合中的数字的最大异或值,最大and值,最大or值
    输入
    第一行1个正整数Q表示操作次数
    接下来Q行,每行2个数字,第一个数字是操作序号OP(1,2),第二个数字是X表示操作的数字
    输出
    输出查询次数行,每行3个整数,空格隔开,分别表示最大异或值,最大and值,最大or值
    样例输入
    【输入样例1】
    5
    1 2
    1 3
    2 4
    1 5
    2 7
    【输出样例1】
    7 0 7
    5 5 7
    【样例解释1】
    询问4时,已插入2、3,最大异或值为4^3=7,最大and值为4&3或4&2=0,最大or值为4|3=7
    询问7时,已插入2、3、5,最大异或值为7^2=5,最大and值为7&5=5,最大or值为7|2=7|3=7|5=7
    【输入样例2】
    10
    1 194570
    1 202332
    1 802413
    2 234800
    1 1011194
    2 1021030
    2 715144
    2 720841
    1 7684
    2 85165
    【输出样例2】
    1026909 201744 1032061
    879724 984162 1048062
    655316 682376 1043962
    649621 683464 1048571
    926039 85160 1011199
    样例输出 [复制]
    提示
    对于%10的数据1<=Q<=5000
    对于另%10的数据保证 X<1024
    对于另%40的数据保证1<=Q<=100000
    对于所有数据保证1<=Q<=1000000,1<=X<=2^20 保证第一个操作为1操作。

    异或操作很简单,建trie树就是了,而&和 | 可以按位贪心

    比如&时,如果x该位已为0,那么0和1都是可以的,于是只需要给子集打标记,默认填0

    |也是基本上一样的

    代码

    #include<bits/stdc++.h>
    using namespace std;
    int q,trans[(1<<21)+3][2],tot=1,op,x;
    inline int read(){
        char ch;
        while((ch=getchar())<'0'||ch>'9'){;}
        int res=ch-'0';
        while((ch=getchar())>='0'&&ch<='9')
        res=res*10+ch-'0';
        return res;
    }
    int le[1<<20];
    inline void mark(int x)
    {
        le[x]=1;
        for(int i=0;i<20;i++)
        {
            if((x>>i&1)&&(!le[x^(1<<i)])) mark(x^(1<<i));
        }
    }
    inline void insert(int k)
    {
        int p=1;
        for(int i=19;~i;i--)
        {
            int c=(k>>i&1?1:0);
            if(!trans[p][c]) trans[p][c]=++tot;
            p=trans[p][c];
        }
    }
    inline int find(int k)
    {
        int p=1,now=0;
        for(int i=19;~i;i--)
        {
            int c=(k>>i&1?0:1);
            if(trans[p][c])
            {
                p=trans[p][c];
                if(c)
                now|=1<<i;
            }
            else
            {
                p=trans[p][c^1];
                if(c^1) now|=1<<i;
            }
        }
        return now;
    }
    int main(){
        q=read();
        for(int o=1;o<=q;o++)
        {
            op=read(),x=read();
            if(op==1)
            {
                mark(x);
                insert(x);
            }
            else
            {
                printf("%d ",find(x)^x);
                int now=0;
                for(int i=19;~i;i--)
                {
                    if((x>>i&1)&&le[now|1<<i]) now|=1<<i;
                }
                printf("%d ",now&x);
                now=0;
                for(int i=19;~i;i--)
                {
                    if((!(x&(1<<i)))&&le[now|1<<i]) now|=1<<i;
                }
                printf("%d
    ",now|x);
            }
        }
    }
  • 相关阅读:
    Kubernetes 集成研发笔记
    Rust 1.44.0 发布
    Rust 1.43.0 发布
    PAT 甲级 1108 Finding Average (20分)
    PAT 甲级 1107 Social Clusters (30分)(并查集)
    PAT 甲级 1106 Lowest Price in Supply Chain (25分) (bfs)
    PAT 甲级 1105 Spiral Matrix (25分)(螺旋矩阵,简单模拟)
    PAT 甲级 1104 Sum of Number Segments (20分)(有坑,int *int 可能会溢出)
    java 多线程 26 : 线程池
    OpenCV_Python —— (4)形态学操作
  • 原文地址:https://www.cnblogs.com/forever-/p/9736088.html
Copyright © 2011-2022 走看看