Trie树模板2

Trie数模板2 problem

这道题然后我们求最大异或对,我们很容易想出来 O(n2) 的做法,两层循环遍历搞定

然后我们知道这样是肯定是肯定过不了的,我们考虑用字典树解决,然后我们来看如何插入和查找。

具体操作

我们考虑先插入再查找,因为刚开始字典树是空的,如果先查找是不行的。

1.插入

跟上一篇差不多,我们就当没有相同分支的时候,就新建一个分支就行了,由于是二进制,所以分支最多为两个,这也是跟上一篇插入字符串不一样的地方。

2.查找

我们首先得知道,异或运算的基本原理,这里稍微阐述一下

11001 ^10101 -------- 01101

某一位两个数这一位的值相等,值为0,反之为1

所以我们再进行查找的时候,要尽力查找位数上的值不一样的才行!当然,如果没有,就只能将就,我们这里边查找边计算就可以了,每次将值乘 2 在加上查找的值就行了。

#include <iostream> #include <cstring> #include <algorithm> using namespace std; const int N = 1e5 + 10; int n; int a[N]; int son[N * 31][2], idx;//二进制 void insert(int x) { int p = 0; for (int i = 30; i >= 0; i -- ) { int u = x >> i & 1;//取出来这一位二进制是多少 if(!son[p][u]) son[p][u] = ++ idx; p = son[p][u]; } } int query(int x) { int p = 0, res = 0; for (int i = 30; i >= 0; i -- ) { int u = x >> i & 1; if(son[p][!u]) { p = son[p][!u]; res = res * 2 + !u; } else { p = son[p][u]; res = res * 2 + u; } } return res; } int main() { scanf("%d", &n); for (int i = 0; i < n; i ++ ) scanf("%d", &a[i]); int res = 0; for (int i = 0; i < n; i ++ ) { insert(a[i]); int t = query(a[i]); res = max(res, a[i] ^ t); } printf("%d\n",res); return 0; }

__EOF__

本文作者ljfyyds
本文链接https://www.cnblogs.com/ljfyyds/p/16505536.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   ljfyyds  阅读(162)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示