Tries
Tries tree is a data structure used to efficiently store and find string sets
for example
The following five strings Tries as follows abbcca adacaa bcc bccac And mark the word node at the end of each character (indicating that there are words that have ended at this point) It can efficiently find whether a string appears in the collection and the number of occurrences for example lookup "bcc" root -> b -> c -> c(Tag found successfully) lookup "abbc" root -> a -> b -> b -> c (here c Node is not marked and does not exist to c Ending word)
Trie string statistics
Title Description
Maintain a string collection and support two operations:
I x inserts a string x into the set;
Q x asks how many times a string appears in the set.
There are N operations in total. The total length of the input string does not exceed 105. The string contains only lowercase English letters.
Input format
The first line contains the integer N, which represents the operand.
Next N lines, each line contains an operation instruction, which is one of I x or Q x.
Output format
For each query instruction Q x, an integer is output as the result, indicating the number of times x appears in the set.
One line for each result.
Data range
1 ≤ N ≤ 2 ∗ 1 0 4 1≤N≤2∗10^4 1≤N≤2∗104
Input example:
5 I abc Q abc Q ab I ab Q ab
Output example:
1 0 1
Problem solution
The key to the creation and search of Tries tree is two functions and, s o n [ N ] [ 26 ] , i d x , c n t [ N ] son[N][26], idx, cnt[N] son[N][26],idx,cnt[N]
s [ i ] [ j ] s[i][j] s[i][j] means the child node of the current i-th node and stores the node address of the j-th letter (understood as address)
c n t [ i ] cnt[i] cnt[i] the number of times the word in the ith node appears as the end ()
i d x idx idx creates a new node subscript (creates a new analog address, which is understood to be equivalent to a new address)
Note: the root node = = 0 is empty
code
#include <bits/stdc++.h> using namespace std; const int N = 10010; int son[N][26], idx, cnt[N]; void insert(char str[]) { int p = 0; for (int i = 0; str[i]; i ++) { int u = str[i] - 'a'; //Get letter mapping if (!son[p][u]) son[p][u] = ++ idx; //If the address subscript is empty, it means that it has not been created, and duplicate creation is prevented p = son[p][u]; // p is the traversal pointer to the child node just created } cnt[p] ++; //Mark the node at the end of the last word p is the pointer } int query(char str[]) { int p = 0; for (int i = 0; str[i]; i ++) { int u = str[i] - 'a'; if (!son[p][u]) return 0; //If the letter is not changed in the child node that the current p points to, the string does not exist p = son[p][u]; } return cnt[p]; } int main() { int n; cin >> n; while (n -- ) { char op[2], str[N]; scanf("%s%s",op, str); if (op[0] == 'I') insert(str); else printf("%d\n", query(str)); } return 0; }
Maximum XOR pair
Title Description
In the given N integers A 1 , A 2 ... ... , A N A_1,A_2......, A_N Select two from A1, A2... And AN to perform xor operation. What is the maximum result?
Input format
Enter an integer N on the first line.
Enter N integers on the second line A 1 ~ A N A_1~A_N A1~AN.
Output format
Output an integer representing the answer.
Data range
1
≤
N
≤
1
0
5
,
1≤N≤10^5,
1≤N≤105,
0
≤
A
i
<
2
31
0≤A_i<2^{31}
0≤Ai<231
Input example:
3 1 2 3
Output example:
3
Problem solution
First, violent practices O ( n 2 ) O(n^2) O(n2)
for (int i = 0; i < n; i ++) for (int j = 0; j <= i; i++) { ans = max(ans,a[i] ^ a[j]) }
We try to optimize the inner loop
The meaning of inner loop: find a number and a [ i ] a[i] a[i] maximum XOR value
First of all, the XOR value is the largest, that is, starting from the highest bit, the binary digits are different, and each bit is like this. The last number found must be the number with the largest XOR a[i] value
After we convert a number into binary, we use the Tries tree to save it
When searching, use res to record the corresponding decimal
After optimization, the inner layer from O ( n ) O(n) The time complexity of O(n) becomes the worst at the constant level O ( 31 ) O(31) O(31)
The overall complexity is close to O ( n l o g n ) O(nlog_n) O(nlogn)
code
#include <bits/stdc++.h> using namespace std; const int N = 100010; int son[N*31][2], idx; int a[N]; 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]) //If XOR wants to find a child node with different digits, judge the child node of the node first! Whether u exists { res = res * 2 + !u; p = son[p][!u]; } else { res = res * 2 + u; p = son[p][u]; } } return res ^ x; } int main() { int n, ans = 0; cin >> n; for (int i = 0; i < n; i++) scanf("%d", &a[i]); for (int i = 0; i < n; i ++) { insert(a[i]); ans = max(ans,query(a[i])); } cout << ans; return 0; }