$\newcommand{\O}{\mathrm{O}}$
Trie(トライ)木とよばれる木構造を構築するアルゴリズム. 文字列集合を効率的に管理することのできるデータ構造(同様のアルゴリズム).
例えば, $n$ 個の文字列集合を受け取ってそのあとクエリとして "(長さ $x$ の) $s$ という文字列はその中に含まれていますか" というものを処理する際 set などを使うと $\O (x \log n)$ かかってしまうが Trie 木を用いると $\O (x)$ と線形で線形で判定することができる.
構造自体はとても単純で, 言葉で説明するより図を見たほうが早いと思うので他の方の説明ページを参考にしてください(図を作れない...).
時間計算量: 構築, クエリ $\O (L)$ ($L$ = 挿入する文字列の総長)
class Trie { public: struct Node { Node *next[26]; int sub; Node() : sub(0){ for(int i = 0; i < 26; i++){ next[i] = nullptr; } } }; Node* root; Trie(){ root = new Node(); } //Trie木にxを加える void add(string& s) { Node *curr = root; for(int i = 0; i < (int)s.size(); i++){ int y = s[i] - 'a'; if (!curr->next[y]) { curr->next[y] = new Node(); } curr->sub++; curr = curr->next[y]; } curr->sub++; } //何らかのクエリ int query(Node *curr,int d) { int res = 0; for(int i = 0; i < 26; i++){ if(curr->next[i]){ res += query(curr->next[i],d+1); } } return res; } int query() { return query(root, 0); } };
Codeforces : Short Code 提出コード