Trie树/字典树题目(2017今日头条笔试题:异或)
/*
本程序说明: [编程题] 异或
时间限制: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今日头条笔试题:异或)的更多相关文章
- 剑指Offer——完美+今日头条笔试题+知识点总结
剑指Offer--完美+今日头条笔试题+知识点总结 情景回顾 时间:2016.9.28 16:00-18:00 19:00-21:00 地点:山东省网络环境智能计算技术重点实验室 事件:完美世界笔试 ...
- 2018春招-今日头条笔试题-第四题(python)
题目描述:2018春招-今日头条笔试题5题(后附大佬答案-c++版) #-*- coding:utf-8 -*- class Magic: ''' a:用于存储数组a b:用于存储数组b num:用于 ...
- 2018春招-今日头条笔试题-第三题(python)
题目描述:2018春招-今日头条笔试题5题(后附大佬答案-c++版) 解题思路: 本题的做法最重要的应该是如何拼出‘1234567890’,对于输入表达试获得对应的结果利用python内置函数eval ...
- 2018春招-今日头条笔试题-第二题(python)
题目描述:2018春招-今日头条笔试题5题(后附大佬答案-c++版) 解题思路: 利用深度优先搜索 #-*- coding:utf-8 -*- class DFS: ''' num:用于存储最后执行次 ...
- 2018春招-今日头条笔试题-第一题(python)
题目描述:2018春招-今日头条笔试题5题(后附大佬答案-c++版) 解题思路: 要想得到输入的数字列中存在相隔为k的数,可以将输入的数字加上k,然后判断其在不在输入的数字列中即可. #-*- cod ...
- 2018春招-今日头条笔试题5题(后附大佬答案-c++版)
1题目描述 在n个元素的数组中,找到差值为k的除重后的数字对 输入描述 第一行:n和k,n表示数字的个数,k表示差值 第二行:n个整数 输入样例 输入: 5 2 1 5 3 4 2 输出: 3 说明: ...
- 剑指Offer——Trie树(字典树)
剑指Offer--Trie树(字典树) Trie树 Trie树,即字典树,又称单词查找树或键树,是一种树形结构,是一种的单词.对于每一个单词,我们要判断他出没出现过,如果出现了,求第一次出现在第几个位 ...
- AC自动机——1 Trie树(字典树)介绍
AC自动机——1 Trie树(字典树)介绍 2013年10月15日 23:56:45 阅读数:2375 之前,我们介绍了Kmp算法,其实,他就是一种单模式匹配.当要检查一篇文章中是否有某些敏感词,这其 ...
- Trie(字典树)
没时间整理了,老吕又讲课了@ @ 概念 Trie即字典树,又称单词查找树或键树,是一种树形结构,是一种哈希树的变种,典型应用是统计和排序大量的字符串(不限于字符串) Trie字典树主要用于存储字符串, ...
随机推荐
- Vue中的$set的使用
在我们使用vue进行开发的过程中,可能会遇到一种情况:当生成vue实例后,当再次给数据赋值时,有时候并不会自动更新到视图上去: 当我们去看vue文档的时候,会发现有这么一句话:如果在实例创建之后添加新 ...
- Android中与task相关的几个属性
1.与任务相关的属性 taskAffinity :修改任何给定Activity的关联 系统使用包名标识应用的默认任务关联: taskAffinity属性取字符串值,必须不同于包名: taskAffin ...
- 98、vue.js简单入门
本篇导航: 介绍与安装 vue常用指令 一.介绍与安装 vue是一套构建用户界面的JAVASCRIPT框架.与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用.Vue 的核心库只关注视图层, ...
- 【JavaScript_轮播图】
今天给大家带来的是我自己做的一个轮播图效果,让我们一起来学习一下吧. 这是我的页面所有代码: <!DOCTYPE html> <html> <head> <m ...
- [基础常识]申请免费SSL证书 - 阿里云云盾证书 - Digicert+Symantec 免费型DV SSL
https://bbs.aliyun.com/read/573933.html?spm=5176.10695662.1996646101.searchclickresult.72be06dct9Qvw ...
- 访问网时出现403 Forbidden错误的原因:
1.你的IP被列入黑名单.2.你在一定时间内过多地访问此网站(一般是用采集程序),被防火墙拒绝访问了.3.网站域名解析到了空间,但空间未绑定此域名.4.你的网页脚本文件在当前目录下没有执行权限.5.在 ...
- Codeforces 448 E. Divisors (DFS,储存结构)
题目链接:E. Divisors 题意: 给出一个X,f(X)是X所有约数的数列(例6:1 2 3 6),给出一个k,k是递归的次数(例:k=2 : f(f(X)) ; X=4,k=2: 1 1 2 ...
- Java泛型类和泛型方法
java编程思想说道: 泛型类是应用在整个类上,但同时可以在类中包含参数化方法,而这个方法所在的类可以是泛型,也可以不是泛型,也就是说是否有泛型方法,与其所在的类是否是泛型类没有关系. 泛型方法是的该 ...
- Mac下用SSH连接远程Linux或Mac服务器
1.打开Mac终端 2.切换到root登录 输入命令:sudo -i,然后输入本机密码 p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px &qu ...
- Redis 2种持久化模式的缺陷
http://blog.csdn.net/hexieshangwang/article/details/47254087 一.RDB持久化模式缺陷 1.问题描述: 并发200路,模拟不断写Redis, ...