xorand

描述

有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操作。

异或查询显然是01trie+贪心的常规套路,但问题就在于如何处理与和或的情况。

事实上,对于与操作,我们只考虑其为1的二进制位集合中有没有对应的数该位也为一。或操作类似,因此我们对于插入01trie的每一个数,将由其为1的二进制位下标组成的所有集合都给标记一遍,之后用类似于处理异或的方法从高到低位贪心缩小范围即可。

注意标记是可以记忆化的,所以时间复杂度有保证。

代码:

#include<bits/stdc++.h>
#define N 2000010
#define P 19
#define max(x,y) (x>y?x:y)
using namespace std;
inline int read(){
    int ans=0;
    char ch=getchar();
    while(!isdigit(ch))ch=getchar();
    while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
    return ans;
}
inline void write(int x){
    if(x>9)write(x/10);
    putchar((x%10)^48);
}
int cnt=1,q,a[N],rt=1,son[N][2],flag[N],ans1,ans2,ans3;
inline void makeflag(int x){
    flag[x]=1;
    for(int i=0;i<=P;++i)if((x>>i&1)&&(!flag[x^(1<<i)]))makeflag(x^(1<<i));
}
inline void insert(int x){
    int p=rt;
    for(int i=P;~i;--i){
        int c=(x>>i)&1;
        if(!son[p][c])son[p][c]=++cnt;
        p=son[p][c];
    }
}
inline int query(int x){
    int p=rt,ret=0;
    for(int i=P;~i;--i){
        int c=((x>>i)&1^1);
        if(son[p][c]){
            p=son[p][c];
            if(c)ret|=1<<i;
        }
        else{
            p=son[p][c^1];
            if(c^1)ret|=1<<i;
        }
    }
    return ret^x;
}
inline int query1(int x){
    int p=rt,ret=0;
    for(int i=P;~i;--i){
        int c=(x>>i)&1;
        if(!c)continue;
        if(flag[ret|(1<<i)])ret|=(1<<i);
    }
    return ret&x;
}
inline int query2(int x){
    int p=rt,ret=0;
    for(int i=P;~i;--i){
        int c=(x>>i)&1;
        if(c)continue;
        if(flag[ret|(1<<i)])ret|=(1<<i);
    }
    return ret|x;
}
int main(){
    q=read();
    while(q--){
        int op=read(),x=read();
        if(op==1)makeflag(x),insert(x);
        else{
            write(query(x)),putchar(' ');
            write(query1(x)),putchar(' ');
            write(query2(x)),putchar('\n');
        }
    }
    return 0;
}

2018.08.21 NOIP模拟 xorand(01trie)的更多相关文章

  1. 2018.08.21 NOIP模拟 unlock(模拟+找规律)

    unlock 描述 经济危机席卷全球,L国也收到冲击,大量人员失业. 然而,作为L国的风云人物,X找到了自己的新工作.从下周开始,X将成为一个酒店的助理锁匠,当然,他得先向部门领导展示他的开锁能力. ...

  2. 2018.08.22 NOIP模拟 string(模拟)

    string [描述] 给定两个字符串 s,t,其中 s 只包含小写字母以及*,t 只包含小写字母. 你可以进行任意多次操作,每次选择 s 中的一个*,将它修改为任意多个(可以是 0 个)它的前一个字 ...

  3. 2018.08.30 NOIP模拟 wall(模拟)

    [问题描述] 万里长城是中国强大的标志,长城在古代的用途主要用于快速传递军事消息和抵御 外敌,在长城上的烽火台即可以作为藏兵的堡垒有可以来点燃狼烟传递消息. 现在有一段 万里长城,一共有 N 个烽火台 ...

  4. 2018.08.29 NOIP模拟 movie(状压dp/随机化贪心)

    [描述] 小石头喜欢看电影,选择有 N 部电影可供选择,每一部电影会在一天的不同时段播 放.他希望连续看 L 分钟的电影.因为电影院是他家开的,所以他可以在一部电影播放过程中任何时间进入或退出,当然他 ...

  5. 2018.08.19 NOIP模拟 change(简单模拟)

    Change 题目背景 SOURCE:NOIP2015-SHY-10 题目描述 Alice 和 Bob 又聚在一起了!他们已经厌倦了取石子游戏,现在他们热衷于切题.于是,Alice 找到了一道题让 B ...

  6. 2018.08.30 NOIP模拟 graph(dfs序/树剖+线段树)

    [描述] 给你一个图,一共有 N 个点,2*N-2 条有向边. 边目录按两部分给出 1. 开始的 n-1 条边描述了一颗以 1 号点为根的生成树,即每个点都可以由 1 号点 到达. 2. 接下来的 N ...

  7. 2018.08.30 NOIP模拟 kfib(矩阵快速幂+exgcd)

    [输入] 一行两个整数 n P [输出] 从小到大输出可能的 k,若不存在,输出 None [样例输入 1] 5 5 [样例输出] 2 [样例解释] f[0] = 2 f[1] = 2 f[2] = ...

  8. 2018.08.29 NOIP模拟 table(拓扑排序+建图优化)

    [描述] 给出一个表格,N 行 M 列,每个格子有一个整数,有些格子是空的.现在需要你 来做出一些调整,使得每行都是非降序的.这个调整只能是整列的移动. [输入] 第一行两个正整数 N 和 M. 接下 ...

  9. 2018.08.29 NOIP模拟 pmatrix(线性筛)

    [问题描述] 根据哥德巴赫猜想(每个不小于 6 的偶数都可以表示为两个奇素数之和),定义 哥德巴赫矩阵 A 如下:对于正整数对(i,j),若 i+j 为偶数且 i,j 均为奇素数,则 Ai,j = 1 ...

随机推荐

  1. 获取DataView行数据

      1.  dv.Table.Rows[0]["price"].ToString();这种方法虽然很长,但意思很清晰. 2.  dv[0]["price"].T ...

  2. idea中创建多module的maven工程

    以前自学Java web的时候,我们都是创建一个web工程,该工程下面再创建dao.service.controller等包.自从工作以后,我们会发现现在的web项目包含多个module,contro ...

  3. Mysql 触发器 A表记录到B表

    1:查询出需要的列名 备用 #列名 select COLUMN_NAME from information_schema.columns where TABLE_SCHEMA='yunpiaobox_ ...

  4. webserive学习记录3-eclipse创建webservice

    在用J2EE版的ECLIPSE学习WEBSERVICE的时候发现原来直接用该ECLIPSE就可以创建webservice,然后就自己动手用ECLIPSE自带的功能来建立WEBSERVICE服务端和客户 ...

  5. 锋利的BFC

    在初学前端的时候,我们会经常碰到各种各样的布局问题,尤其当使用浮动的时候,然而学习了BFC之后,其中的一些怪异现象,也因此成为理所当然,会有一种拨开云雾的快感. 下面简单介绍下BFC,究竟什么是BFC ...

  6. Python Env

    简介: 记录 CentOS 6.x Python 环境的安装步骤. 一.安装依赖包 shell > yum -y install epel-release shell > yum -y i ...

  7. Oracle VM VirtualBox做好虚拟硬盘后,如何进一步修改虚拟硬盘的大小

    以管理员身份打开, 命令提示符窗口,然后利用命令cd进入Oracle VM VirtualBox安装目录,如下图: 我进入了Oracle VM VirtualBox安装目录:D:\Program Fi ...

  8. SQL 数据库 子查询及示例

    子查询,又叫做嵌套查询. 将一个查询语句做为一个结果集供其他SQL语句使用,就像使用普通的表一样,被当作结果集的查询语句被称为子查询. 子查询有两种类型: 一种是只返回一个单值的子查询,这时它可以用在 ...

  9. 删除临时表空间ora-25152错误

    删除临时表空间,或者收缩临时表空间经常会出现表空间占用等情况. 下面我们就对这种情况进行处理, 首先查找被锁的sid: SELECT a.INST_ID,b.TABLESPACE , b.segfil ...

  10. 我在JS上解惑之路1

    1.为什么既然存在等号(==)非等号  (!=),又会有全等号(===)非全等号(!==)? *唯一的不同是后者判断时不进行类型转换. 例:var sNum = "66"; var ...