2017西安交大ACM小学期 有趣异或[Trie树]
2017-07-10 19:39
405 查看
有趣异或
发布时间: 2017年7月4日 23:59 最后更新: 2017年7月5日 14:56 时间限制: 1500ms 内存限制: 512M描述
给定n个非负整数,保证这些数两两不相同。现给定x,请从中选2个不同的数a,b,使得a^b^x最大。
输入
包含多组测试数据。
每组测试数据第一行有1个正整数和1个非负整数,分别为n和x。
接下来一行有n个正整数。
所有数据满足n≤106,所有非负整数以及x小于等于109。
总数据量∑n≤106。
输出
对每组数据输出一行1个整数,表示a^b^x的最大值是多少。
样例输入1 复制
3 0 1 2 3
样例输出1
3
首先,我们把所有的整数对应的二进制前面补0,补成30位的二进制数,然后把这串二进制数当成字符串,存入Trie树中。
其次,我们遍历所有的数a,然后我们寻找b,使得a^b^x最大
我们这样分析,当a和x确定时候a^x也就确定了设a^x = t
那么欲使t^b最大,那么t与b的相同的位上,值应该尽可能的不同,所以,我们依据t的位,在Trie中寻找b。。。
这里有一个坑点,那就只注意a和b不能相同,如果数据是x = (1111111....)b的话,那么朴素的求会找到与a相等的b,这显然是错误的
因此,可以用一个标记,代表当前搜索到的Trie树位置是否可能得到与a相等的b,搜索时候注意就好了。
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int MAX = 1e6+7; int n,x; int a[MAX]; struct trie { int count; trie* child[2]; }; trie* root; void build(int num){ trie* p = root; for(int i = 29;i >= 0;i--){ int key = (num>>i) & 1; if(!p -> child[key]){ trie* nt = new trie; nt -> count = 1; nt -> child[0] = nt -> child[1] = 0; p -> child[key] = nt; p = nt; } else{ p = p -> child[key]; p -> count ++; } } } int find(int a){ int res = 0; trie* p = root; int able = 1; for(int i = 29;i >= 0;i--){ int f = (x>>i) & 1; if(f){ int key = (a>>i) & 1; if(!p->child[key]) { //没有相同位 able = 0; key ^= 1; }else{ //有相同位 if(!able){ //已经不可能.直接选 res |= (1<<i); } else{ //还可能 if(p->child[key]->count-1 == 0){ //不能选 able = 0; key ^= 1; } else{ //可以选 // todo res |= (1<<i); } } } p = p -> child[key]; } else{ //最好不同 int key = (a>>i) & 1 ^ 1; //key 为理想 if(p->child[key]){ //有不同位 able = 0; res |= (1<<i); } else{ //只有相同位 key ^= 1; } p = p -> child[key]; } } return res; } int main(){ while(~scanf("%d%d",&n,&x)){ int ma = 0; root = new trie; root -> count = 0; root -> child[0] = root -> child[1] = 0; for(int i = 0;i < n;i++){ scanf("%d",&a[i]); build(a[i]); } for(int i = 0;i < n;i++){ ma = max(ma,find(a[i])); } printf("%d\n",ma); } return 0; }
相关文章推荐
- 2017西安交大ACM小学期数据结构 [又是树状数组、异或]
- 2017西安交大ACM小学期 敏感词汇[AC自动机]
- 2017西安交大ACM小学期 刁钻的顾客[3进制+折半枚举]
- 2017西安交大ACM小学期 毁灭序列[倒跑并查集]
- 2017西安交大ACM小学期数据结构 [线段树]
- 2017西安交大ACM小学期数据结构 [树状数组]
- 2017西安交大ACM小学期数据结构 [树状数组,极大值]
- 2017西安交大ACM小学期数据结构 [树状数组 离散化]
- 2017西安交大ACM小学期数论 [阅兵式]
- 2017西安交大ACM小学期数论 [水题]
- 2017西安交大ACM小学期 神器插座 KMP匹配
- 2017西安交大ACM小学期 文本查找[AC自动机]
- 2017西安交大ACM小学期数据结构 [分块,区间修改,单点查询]
- 2017西安交大ACM小学期数论 [完全平方数]
- 2017西安交大ACM小学期数论 [更新学号]
- 2017西安交大ACM小学期 美妙音乐[差分KMP匹配]
- 2017西安交大ACM小学期数论 [等差数列]
- 2017西安交大ACM小学期数据结构 [分块、二维矩阵]
- Trie树/字典树题目(2017今日头条笔试题:异或)
- 2017ACM/ICPC广西邀请赛 K- Query on A Tree trie树合并