1. 程式人生 > 實用技巧 >[模板][字串] Trie樹

[模板][字串] Trie樹

題面
https://oi-wiki.org/string/trie/#_5

所以感覺Trie樹就是通過重複利用相同區間做到減小時間和空間的複雜度效果
不要亂搞

// 雖然好像並不是個 Trie 題但是可以用來當 Trie 板子(霧)
// 就比普通 Trie 多了個計數器

# include <iostream>
# include <cstdio>
# include <cstring>
# include <string>
# include <map>
# define MAXN 500050

using namespace std;

int trie[MAXN][26], cntT; // cntT 為下一個節點位置,亂搞會GG
bool isEnd[MAXN]; // 記錄某個位置是不是結尾節點

void Insert(string s){
	int len = s.length(), p = 1; // p 是一個初始時指向根節點,最後指向末尾節點的指標。
	for(int i = 0, ch; i < len; i++){ // 注意嚴格小於以及 i = 0
		ch = s[i] - 'a';
		if(!(trie[p][ch])){
			trie[p][ch] = ++cntT;
		}
		p = trie[p][ch]; // 更新結尾位置
	}
	isEnd[p] = 1; // 記錄當前節點是結尾節點
}

bool Search(string s){
	int len = s.length(), p = 1;
	for(int i = 0, ch; i < len; i++){ // 注意嚴格小於以及 i = 0
		ch = s[i] - 'a';

		if(!p){
			return 0;
		} // 節點不存在

		p = trie[p][ch]; // 向下查詢
	}

	return isEnd[p];
}

map<string, bool>mp;

int main(){
	memset(trie, 0, sizeof(trie));
	memset(isEnd, 0, sizeof(isEnd));

	int n, m;
	cin>>n;
	string s;
	for(int i = 1; i <= n; i++){
		cin>>s;
		Insert(s);
	}

	cin>>m;

	for(int i = 1; i <= m; i++){
		cin>>s;
		bool ans = Search(s);
		if(ans){
			if(mp[s]){
				cout<<"REPEAT"<<endl;
			}
			else{
				cout<<"OK"<<endl;
				mp[s] = 1;
			}
		}
		else{
			cout<<"WRONG"<<endl;
		}
	}

	return 0;
}