关于异或_字典树的一些性质

异或的性质

1. a ⊕ a = 0

2. a ⊕ b = b ⊕ a

3. a ⊕b ⊕ c = a ⊕ (b ⊕ c) = (a ⊕ b) ⊕ c;

4. d = a ⊕ b ⊕ c 可以推出 a = d ⊕ b ⊕ c.

5. a ⊕ b ⊕ a = b.     自反性

6.若x是二进制数0101,y是二进制数1011;

则x⊕y=1110

只有在两个比较的位不同时其结果是1,否则结果为0

即“两个输入相同时为0,不同则为1”!

字典树:
又称为Trie,是一种用于快速检索的多叉树结构。Trie把要查找的关键词看作一个字符序列,并根据构成字符的先后顺序构造用于检索的树结构;一棵m度的Trie树或者为空,或者由m棵m度的Trie树构。
特点:和二叉树不同的是,他每个节点上并非指出村一个元素

字典树:我的理解就是把每个节点的度数都设为一个相应大小的数组,然后将字母给打进去
trie的数据结构定义:
#define MAX 26;
typeof struct Trie
{
Trie next[MAX];
int v;
};
Trie *root;

生成字典树:
void creatTrie(char *str)
{
int len=strlen(str);
Trie *p=root,*q;
for(int i=0;i<len;i++)
{ int id=str[i]-‘0‘;
if(p->next[id]==0)
{
q=(Trie *)malloc(sizeof(Tire));
q->v=1;//初始v==1
for(int j=0;j<MAX;++j)
q->next[j]=null;
p->next[id]=q;
p=p->next[id];
}
else
{
p->next[id]->v++;
p=p->next[id];
}
}
p->v=-1; //若为结尾,则将v改成-1表示
}

查找树:
Code highlighting produced by Actipro CodeHighlighter (freeware)
{
int len = strlen(str);
Trie *p = root;
for(int i=0; i<len; ++i)
{
int id = str[i]-‘0‘;
p = p->next[id];
if(p == NULL) //若为空集,表示不存以此为前缀的串
return 0;
if(p->v == -1) //字符集中已有串是此串的前缀
return -1;
}
return -1; //此串是字符集中某串的前缀
}

}

删除树:

Code highlighting produced by Actipro CodeHighlighter (freeware)
{
int i;
if(T==NULL)
return 0;
for(i=0;i<MAX;i++)
{
if(T->next[i]!=NULL)
deal(T->next[i]);
}
free(T);
return 0;
}

代码并不是自己编的还请见谅啦,但是有问题可以提问。

时间: 2024-10-26 07:16:24

关于异或_字典树的一些性质的相关文章

hdu5269 ZYB loves Xor I 异或,字典树

hdu5269  ZYB loves Xor I   异或,字典树 ZYB loves Xor I Accepts: 142 Submissions: 696 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) 问题描述 ZYB喜欢研究Xor,现在他得到了一个长度为nn的数组A.于是他想知道:对于所有数对(i,j)(i \in [1,n],j \in [1,n])(i,j)(i∈[1,n

# [AcWing143] 最大异或和 [字典树]

[AcWing143] 最大异或和 [字典树] 传送门 题意 给出N个整数,选择两个整数,使得异或和最大(\(0<A_i<2^{31}\)) 思路 从数据范围很容易想到二进制,进而想到字典树Trie. 字典树的典型应用是存储字符串,存储二进制也是一样的. 我一开始在处理取二进制位的时候想的比较麻烦,我是使用右移运算符先预处理出每个数的二进制表示,再根据二进制表示插入字典树中.后来了解到x >> i & 1;可以直接取二进制数的任意一位,这样简单了许多. 查询的时候,先取出对

NEUOJ711 异星工厂 字典树+贪心

题意:你可以收集两个不相交区间的权值,区间权值是区间异或,问这两个权值和最大是多少 分析:很多有关异或求最大的题都是利用01字典树进行贪心,做这个题的时候我都忘了...最后是看别人代码的时候才想起来这个套路 l[i],记录,从 1 到 i  里 最大的异或区间权值, r[i], 记录,从  i 到 n 里 最大的异或区间权值 这样两轮插入,然后查询贪心就行了,插入的是前缀和后缀的异或2进制序列,从大的开始(贪心) 注:吐槽,其实都是套路,异或和求最大,往往要利用字典树进行贪心 #include

POJ 3764 The xor-longest Path 字典树求最大异或

题意,一颗树,每个边有个值,在树上找一条简单路径,使得这条路径上的边权异或值最大 把这题模型转换一下, 对于任意一条路径的异或,表示为f(u, v) 则f(u, v) = f(1, u) ^ f(1, v) 这是显然的 其中f(1, i)是可以再O(n)内处理出来 然后就是在一个数组内,找两个数异或值最大 然后就可以用字典树来搞 每个数变成01串,  然后插入字典树, 第30位在最前,然后29,依次到0位 就建立成了一个深度为31的字典树 对于一个询问,在字典树上找,就是尽量找跟其相反的路径.

[01字典树]求序列完美度(求区间最大异或值)

https://nanti.jisuanke.com/t/15531 解题关键:01字典树模板,用字典树保存每个数的二进制表示,从而动态维护区间上的最大异或值,注意添加和删除都可以用于一个change函数表示. 复杂度:$O(n\log n + {n^2}\log n)$ 1 #include<bits/stdc++.h> 2 #define maxn 1005 3 #define inf 0x3f3f3f3f 4 using namespace std; 5 typedef long lon

Chip Factory---hdu5536(异或值最大,01字典树)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5536 题意:有一个数组a[], 包含n个数,从n个数中找到三个数使得 (a[i]+a[j])⊕a[k]最大,i,j,k不同; 求异或的结果最大所以我们可以用01字典树,先把所有的数加入字典树中,从n个数中选出两个数a[i]和a[j], 先把他们从字典树中删除,然后找到与a[i]+a[j]异或最大的数,和结果取最大值即可: 最后不要忘记再把a[i]和a[j]添加到字典树中即可: #include<st

2014百度之星第三题Xor Sum(字典树+异或运算)

Xor Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others) Total Submission(s): 4445    Accepted Submission(s): 652 Problem Description Zeus 和 Prometheus 做了一个游戏.Prometheus 给 Zeus 一个集合,集合中包括了N个正整数.随后 Prometheus 将向 Ze

POJ 3764 (异或+字典树)

早就听过用字典树求异或最大值,然而没做过.发现一碰到异或的题就GG,而且因为以前做过的一道类似的题(事实上并不类似)限制了思路,蠢啊= =. 题意:一棵带权的树,求任意两点间路径异或的最大值. 题解:设xor(a,b)是求a,b间路径的异或值,那么xor(a,b)=xor(root,a)^xor(root,b).因为如果LCA(a,b)==root时结论显然成立,不然的话就会有重复走过的部分,但是异或有性质x^x=0,所以LCA(a,b)!=root结论依然成立. 这样题目就很简单了.对每一个x

POJ 3764 The xor-longest Path ( 字典树应用—— 求连续段相异或最大最小的线性算法)(好题)

题意:已知:给出n个结点的树,定义:两结点间的权值为两点之间所有边相异或的值.求:树中的某两点间的最大权值. 思路:先说简单一点的题:有道CowXor,是一串线性序列,求某连续段异或的最大值,这题的思路是先求前i项序列相异或的值Si,所以x到y的连续异或就是Sx^Sy ,因为a^b = (a ^ c) ^ (b ^ c). 这题同样是这个思路把线性拓展到树上,先求任何点到某一定点的连续异或值,比如选根结点0,所以这时候有两种情况,1.x,y的路径通过了根结点,显然正确.2.x,y的路径不通过根结