【数据结构-树论】字典树(Trie)
引入
观看例题,可以看出暴力解,时间复杂度大概为 \(O(Tnq)\),最差情况 \(1e15\),我觉得洛谷测评姬没有那么快。
单词哦,查字典,怎么查:
先找第一个字母,再找第二个字母 \(\dots \dots\)
于是乎发明字典树(话说我本来是想用二分做的。)
定义及思想
一种树形结构,基于字符串前缀来进行查找,减少比较,以空间换时间。
作用及实现
多数用于字符串的查找以及排序。
是一个 \(26\) 叉树。
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define pii pair<int, int>
#define mp(x, y) make_pair(x, y)
const int man = 5e5+10;
class Graph {
public:
int len, hed[man];
int ver[man], nxt[man];
void Ins (int u, int v) {
ver[++len] = v;
nxt[len] = hed[u];
hed[u] = len;
return ;
}
void DIns (int u, int v) {
Ins(u, v), Ins(v, u);
return ;
}
} ;
/*
Windows:
g++ test.cpp -o test.exe
get-content .\test.in | .\test.exe > test.out
*/
int n, q, idx;
int cnt[man], flag[man];
int tr[man][30];
void make (string) ;
string check (string) ;
int main () {
#ifndef ONLINE_JUDGE
freopen("test.in", "r", stdin);
freopen("test.out", "w", stdout);
#endif
for(int i = 0; i <= idx; ++ i) {
cnt[i] = 0;
for(int j = 0; j < 26; ++ j) tr[i][j] = 0;
} idx = 0;
scanf("%d", &n);
for (int i = 1; i <= n; ++ i) {
string s;
cin >> s;
make(s);
} scanf("%d", &q);
for (int i = 1; i <= q; ++ i) {
string s;
cin >> s;
cout << check(s);
}
return 0;
}
// ---
void make (string str) {
int p = 0;
for (int i = 0; i < str.length(); ++ i) {
int j = str[i]-'a';
if (!tr[p][j]) tr[p][j] = ++ idx;
p = tr[p][j];
} ++ cnt[p];
return ;
}
string check (string str) {
int res = 0, p = 0, j;
for (int i = 0; i < str.length(); ++ i) {
j = str[i]-'a';
if (!tr[p][j]) return "WRONG\n";
p = tr[p][j];
} return cnt[p]? flag[p]++? "REPEAT\n" : "OK\n" : "WRONG\n";
}

浙公网安备 33010602011771号