#include<iostream>usingnamespace std;constint N =1e5+10;int son[N][26];// 其中存放的是:子节点对应的idx。其中son数组的第一维是:父节点对应的idx,第第二维计数是:其直接子节点('a' - '0')的值为二维下标。int cnt [N];// 以“abc”字符串为例,最后一个字符---‘c’对应的idx作为cnt数组的下标。数组的值是该idx对应的个数。int idx;// 将该字符串分配的一个树结构中,以下标来记录每一个字符的位置。方便之后的插入和查找。char str[N];voidinsert(char*str){
int p =0;for(int i =0; str[i]; i++){
int u = str[i]-'0';if(!son[p][u]) son[p][u]=++idx;p = son[p][u];}// 此时的p就是str中最后一个字符对应的trie树的位置idx。cnt[p]++;}intquery(char*str){
int p =0;for(int i =0; str[i]; i++){
int u = str[i]-'0';if(!son[p][u])return0;p = son[p][u];}return cnt[p];}intmain(){
int n;scanf("%d",&n);char op[2];while(n--){
scanf("%s%s", op, str);if(op[0]=='I')insert(str);elseprintf("%d\n",query(str));}return0;}
2.最大异或对
#include<iostream>#include<algorithm>usingnamespace std;constint N =100010;int a[N], son[N *31][2];// 在trie树中 二维数组son存的是节点的下标 // 第一维就是下标的值 第二维代表着儿子 在本题中 只有0或1 两个儿子int n, idx;//从上向下插入x的二进制树(创建子节点,生成树)voidinsert(int x){
int p =0;for(int i =31; i >=0; i--){
int u = x >> i &1;//取二进制数的某一位的值if(!son[p][u]) son[p][u]=++idx;//如果下标为p的点的u(0或1)这个儿子不存在,那就创建p = son[p][u];}}//树中与x异或的最大值//从下向上求出x的值intquery(int x){
int p =0, ret =0;for(int i =31; i >=0; i--){
int u = x >> i &1;//走相同数字路径if(!son[p][!u])//不存在子节点具有相反数字{
p = son[p][u];//走相同数字路径ret = ret *2+ u;//这个地方与十进制一样 n = n * 10 + x;}//则八进制就是 n = n * 8 + x;//走相反数字路径else//存在子节点具有相反数字{
p = son[p][!u];//走相反数字路径ret = ret *2+!u;}}ret = ret ^ x;return ret;}intmain(){
cin >> n;int maxXorNum =0;//1.边插入边查询2.全部插入完再查询for(int i =0; i < n; i++)//为什么可以边插入边查询,因为:其实3与4异或最大,但是在找3与x异或最大时,此时找到的x是<3的,//随着4的插入,3无法与4异或,但是4与3可以异或,便可以求出最大异或值{
scanf("%d",&a[i]);insert(a[i]);maxXorNum =max(maxXorNum,query(a[i]));}cout<<maxXorNum<<endl;return0;}