/*
本程序说明: [编程题] 异或
时间限制:1秒
空间限制:32768K
给定整数m以及n个数字A1,A2,..An,将数列A中所有元素两两异或,共能得到n(n-1)/2个结果,请求出这些结果中大于m的有多少个。
输入描述:
第一行包含两个整数n,m. 第二行给出n个整数A1,A2,...,An。 数据范围 对于30%的数据,1 <= n, m <= 1000 对于100%的数据,1 <= n, m, Ai <= 10^5 输出描述:
输出仅包括一行,即所求的答案 输入例子1:
3 10
6 5 10 输出例子1:
2 链接:https://www.nowcoder.com/questionTerminal/fc05f68c5f47438db54c6923ef23cf4a
来源:牛客网 /*
C++
思路来源:牛客网“潇潇古月”,在此表示感谢。
思路:
直接计算肯定是超时的,所以这问题不能使用暴力破解,考虑到从高位到地位,依次进行位运算,
如果两个数异或结果在某高位为1,而m的对应位为0,则肯定任何这两位异或结果为1的都会比m大。
由此,考虑使用字典树(TrieTree)从高位到第位建立字典,再使用每个元素依次去字典中查对应
高位异或为1, 而m为0的数的个数,相加在除以2既是最终的结果;直接贴出代码如下,非原创,欢迎讨论;
补充:queryTrieTree在搜索的过程中,是从高位往低位搜索,那么,如果有一个数与字典中的数异或结果
的第k位大于m的第k位,那么该数与对应分支中所有的数异或结果都会大于m, 否则,就要搜索在第k位异或
相等的情况下,更低位的异或结果。queryTrieTree中四个分支的作用分别如下:
1. aDigit=1, mDigit=1时,字典中第k位为0,异或结果为1,需要继续搜索更低位,第k位为1,异或结果为0,小于mDigit,不用理会;
2. aDigit=0, mDigit=1时,字典中第k位为1,异或结果为1,需要继续搜索更低位,第k位为0,异或结果为0,小于mDigit,不用理会;
3. aDigit=1, mDigit=0时,字典中第k位为0,异或结果为1,与对应分支所有数异或,结果都会大于m,第k位为1,异或结果为0,递归获得结果;
4. aDigit=0, mDigit=0时,字典中第k位为1,异或结果为1,与对应分支所有数异或,结果都会大于m,第k位为0,异或结果为0,递归获得结果; 改进:
1.字典树17位即可保证大于100000,移位范围为1~16位,则字典树构建时从16~0即可。
字典树第一层不占位,实际上是15~-1层有数据,这也是数据中next的用法。
2.queryTrieTree函数需要考虑到index为-1时的返回值。 时间复杂度:O(n);
空间复杂度O(k),k为常数(trie树的高度),因此可以认为O(1)。
*/
#include <iostream>
#include <vector>
using namespace std; struct TrieTree
{
int count;//每个节点存的次数
struct TrieTree* next[]{NULL,NULL};//每个节点存储两个节点指针
TrieTree():count(){}
}; TrieTree* buildTrieTree(const vector<int>& array)
{
TrieTree* trieTree = new TrieTree();
for(int i=;i<(int)array.size();++i)
{
TrieTree* cur = trieTree;
for(int j=;j>=;--j)
{
int digit = (array[i] >> j) & ;
if(NULL == cur->next[digit])
cur->next[digit] = new TrieTree();
else
++(cur->next[digit]->count);
cur = cur->next[digit];
}
}
return trieTree;
} //查询字典树
long long queryTrieTree(TrieTree*& trieTree, const int a, const int m, const int index)
{
if(NULL == trieTree)
return ; TrieTree* cur = trieTree; for(int i=index;i>=;--i)
{
int aDigit = (a >> i) & ;
int mDigit = (m >> i) & ; if(==aDigit && ==mDigit)
{
if(NULL == cur->next[])
return ;
cur = cur->next[];
}
else if( == aDigit && ==mDigit)
{
if(NULL == cur->next[])
return ;
cur = cur->next[];
}
else if( == aDigit && == mDigit)
{
long long val0 = (NULL == cur->next[]) ? : cur->next[]->count;
long long val1 = queryTrieTree(cur->next[],a,m,i-);
return val0+val1;
}
else if( == aDigit && == mDigit)
{
long long val0 = queryTrieTree(cur->next[],a,m,i-);
long long val1 = (NULL == cur->next[]) ? : cur->next[]->count;
return val0+val1;
}
}
return ;//此时index==-1,这种情况肯定返回0(其他情况在循环体中都考虑到了)
} //结果可能超过了int范围,因此用long long
long long solve(const vector<int>& array, const int& m)
{
TrieTree* trieTree = buildTrieTree(array);
long long result = ;
for(int i=;i<(int)array.size();++i)
{
result += queryTrieTree(trieTree,array[i],m,);
}
return result /;
} int main()
{
int n,m;
while(cin>>n>>m)
{
vector<int> array(n);
for(int i=;i<n;++i)
cin>>array[i];
cout<< solve(array,m) <<endl;
}
return ;
}

关于trie数的其他应用,可参见http://www.cnblogs.com/dlutxm/archive/2011/10/26/2225660.html,感觉写的不错。

Trie树/字典树题目(2017今日头条笔试题:异或)的更多相关文章

  1. 剑指Offer——完美+今日头条笔试题+知识点总结

    剑指Offer--完美+今日头条笔试题+知识点总结 情景回顾 时间:2016.9.28 16:00-18:00 19:00-21:00 地点:山东省网络环境智能计算技术重点实验室 事件:完美世界笔试 ...

  2. 2018春招-今日头条笔试题-第四题(python)

    题目描述:2018春招-今日头条笔试题5题(后附大佬答案-c++版) #-*- coding:utf-8 -*- class Magic: ''' a:用于存储数组a b:用于存储数组b num:用于 ...

  3. 2018春招-今日头条笔试题-第三题(python)

    题目描述:2018春招-今日头条笔试题5题(后附大佬答案-c++版) 解题思路: 本题的做法最重要的应该是如何拼出‘1234567890’,对于输入表达试获得对应的结果利用python内置函数eval ...

  4. 2018春招-今日头条笔试题-第二题(python)

    题目描述:2018春招-今日头条笔试题5题(后附大佬答案-c++版) 解题思路: 利用深度优先搜索 #-*- coding:utf-8 -*- class DFS: ''' num:用于存储最后执行次 ...

  5. 2018春招-今日头条笔试题-第一题(python)

    题目描述:2018春招-今日头条笔试题5题(后附大佬答案-c++版) 解题思路: 要想得到输入的数字列中存在相隔为k的数,可以将输入的数字加上k,然后判断其在不在输入的数字列中即可. #-*- cod ...

  6. 2018春招-今日头条笔试题5题(后附大佬答案-c++版)

    1题目描述 在n个元素的数组中,找到差值为k的除重后的数字对 输入描述 第一行:n和k,n表示数字的个数,k表示差值 第二行:n个整数 输入样例 输入: 5 2 1 5 3 4 2 输出: 3 说明: ...

  7. 剑指Offer——Trie树(字典树)

    剑指Offer--Trie树(字典树) Trie树 Trie树,即字典树,又称单词查找树或键树,是一种树形结构,是一种的单词.对于每一个单词,我们要判断他出没出现过,如果出现了,求第一次出现在第几个位 ...

  8. AC自动机——1 Trie树(字典树)介绍

    AC自动机——1 Trie树(字典树)介绍 2013年10月15日 23:56:45 阅读数:2375 之前,我们介绍了Kmp算法,其实,他就是一种单模式匹配.当要检查一篇文章中是否有某些敏感词,这其 ...

  9. Trie(字典树)

    没时间整理了,老吕又讲课了@ @ 概念 Trie即字典树,又称单词查找树或键树,是一种树形结构,是一种哈希树的变种,典型应用是统计和排序大量的字符串(不限于字符串) Trie字典树主要用于存储字符串, ...

随机推荐

  1. HDU 5912 Fraction(模拟——分子式化简求解)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5912 Problem Description Mr. Frog recently studied h ...

  2. 什么是redis,redis能做什么,redis应用场景

    Redis是一个key-value存储系统.Redis的出现,很大程度补偿了memcached这类key/value存储的不足,在部分场合可以对关系数据库起到很好的补充作用.这篇文章小编为大家分享了在 ...

  3. 使用pscp命令在Windows与linux之间拷贝文件

    在Linux环境下做开发时,我们可能会在windows下远程控制Linux系统,本文介绍如何使用putty的pscp.exe在Windows和 Linux(本文使用fedora)之间copy文件. 工 ...

  4. 30分钟学玩转RabbitMQ

    最近在学习RabbitMQ,在网上找了不少资料发现都特高端.动辄集群部署,分布式架构什么的,对于一个初学者实在不够友好.心想求人不如求自己,为什么不自己整理一套资料呢?于是<30分钟学玩转Rab ...

  5. SQL中MAX()

    列column_name中的数据可以是数值.字符串或是日期时间数据类型.

  6. 03 整合IDEA+Maven+SSM框架的高并发的商品秒杀项目之web层

    Github:https://github.com/nnngu 项目源代码:https://github.com/nnngu/nguSeckill 前端交互流程设计 对于一个系统,需要产品经理.前端工 ...

  7. Python中执行系统命令常见的几种方法

    (1) os.system 这个方法是直接调用标准C的system() 函数,仅仅在一个子终端运行系统命令,而不能获取命令执行后的返回信息. import os os.system('cat /pro ...

  8. 使用mui框架----移动端页面在所有屏幕下自适应

    写移动端怎么会不用到框架呢? 现在比较火的是mui.amaze UI 之类的,mui是现在最灵活轻便的一个框架,能够从pc到移动灵活的自适应, 只需要调用他定义的类名就能使用,非常方便,只是需要自己来 ...

  9. Linux指令--diff

    diff 命令是 linux上非常重要的工具,用于比较文件的内容,特别是比较两个版本不同的文件以找到改动的地方.diff在命令行中打印每一个行的改动.最新版本的diff还支持二进制文件.diff程序的 ...

  10. Linux指令--rm, rmdir

    rm是常用的命令,该命令的功能为删除一个目录中的一个或多个文件或目录,它也可以将某个目录及其下的所有文件及子目录均删除.对于链接文件,只是删除了链接,原有文件均保持不变.rm是一个危险的命令,使用的时 ...