01字典树板子

来源:互联网 发布:英国大学传媒专业数据 编辑:程序博客网 时间:2024/05/21 06:51

参照了别人的板子http://blog.csdn.net/solardomo/article/details/52168853  ,然后做了几个水题,稍微综合了一下01字典树板子

不用关心代码内部是如何实现的 
只将01字典树看做是一个数集    我们可以在这个集合中查找和X异或最大的元素\异或最小值

板子练习题

https://nanti.jisuanke.com/t/15531

http://codeforces.com/contest/706/problem/D

http://acm.hdu.edu.cn/showproblem.php?pid=4825

https://vjudge.net/problem/LightOJ-1269



const int MAXN = 1000 + 5;struct Trie{    ///如果是LL  则需要改成64 * 数组元素个数    /// 下面的for也是如此  需要改成 i = 64    int ch[32 * MAXN][2];               //节点的边信息    int num[32 * MAXN];                 //节点存储值的个数    LL value[32 * MAXN];                //节点存储的值    int node_cnt;                       //树中当前节点个数    void init()                  //树清空    {        node_cnt = 1;        memset(ch[0],0,sizeof(ch));        memset(num, 0, sizeof(num));    }    void Insert(LL x, int d)            //在字典树中插入d个X    {        //和一般字典树的操作相同 将X的二进制插入到字典树中        int cur = 0;        for(int i = 32; i >= 0; --i)        {            int idx = (x >> i) & 1;            if(!ch[cur][idx])            {                memset(ch[node_cnt],0,sizeof(ch[node_cnt]));                ch[cur][idx] = node_cnt;                value[node_cnt++] = 0;            }            cur = ch[cur][idx];            num[cur] += d;        }        value[cur] = x;             //最后的节点插入value    }    void update(LL x, int d)   //更新x的个数  d为浮动值  可正可负    {        int cur = 0;        for(int i = 32 ; i >= 0 ; i--)        {            int idx = (x >> i) & 1;            cur = ch[cur][idx];            num[cur] += d;        }    }    LL Query(LL x, int dir) //在字典树中查找和X异或的最大值\最小值的元素Y   返回Y的值   dir为1表示寻找异或最大值,为0表示寻找最小值    {        int cur = 0;        for(int i = 32; i >= 0; --i)        {            int idx = (x >> i) & 1;            if(ch[cur][idx ^ dir] && num[ch[cur][idx ^ dir]]) cur = ch[cur][idx ^ dir];            else cur = ch[cur][idx ^ !dir];        }        return value[cur];    }};


原创粉丝点击