#include #include #include #include using namespace std; #define NMAX 100000 struct Trie { map child; }; //root + 30*NMAX , ~(3e6 + 1) //vector pool(30*NMAX + 1, Trie()); vector pool(1, Trie()); //add one extra char-int pair to parent node when each new node is created. //~ O(30*(48 + 8)NMax) 3 = pair //vector word(30*NMAX + 1, false); vector word(1, false); void rte() { *((int *)0) = 1000; } int trie_new() { int res = pool.size(); pool.push_back(Trie()); word.push_back(false); return res; } void trie_insert(int root, const string &s) { int node = root; map::iterator it; for(int i = 0; i < s.size(); i++){ it = pool[node].child.find(s[i]); if(it == pool[node].child.end()){ //child[s[i]] = trie_new() may not update child[s[i]]. //workaround int nxt = trie_new(); pool[node].child[s[i]] = nxt; node = nxt; }else{ node = it->second; } } word[node] = true; } void trie_delete_prefix(int root, const string &s) { int node = root; int n = s.size(); if(n == 0){ return ; } map::iterator it; vector path; path.push_back(root); for(int i = 0; i < n; i++){ it = pool[node].child.find(s[i]); if(it == pool[node].child.end()){ return; } node = it->second; path.push_back(node); } word[node] = false; for(int i = n - 1; i >= 0; i--){ node = path[i + 1]; int parent = path[i]; pool[parent].child.erase(s[i]); //other child-trees or word with shorten prefix if(pool[parent].child.size() || word[parent]){ break; } } } bool trie_search_prefix(int root, const string &s) { int node = root; map::iterator it; for(int i = 0; i < s.size(); i++){ it = pool[node].child.find(s[i]); if(it == pool[node].child.end()){ return false; } node = it->second; } return true; } //6 + 1, 30 + 1 char cmd[10], s[50]; int main(int argc, char **argv) { //pool.size == 1 pool[0] = Trie() word[0] = false int root = 0; int N; //1 1e5 scanf("%d", &N); if((N < 1) || (N > NMAX)){ rte(); } for(int i = 0; i < N; i++){ //|s| in 1 30? scanf("%s%s", cmd, s); switch(cmd[0]){ case 'i': trie_insert(root, s); break; case 'd': trie_delete_prefix(root, s); break; case 's': if(trie_search_prefix(root, s)){ puts("Yes"); }else{ puts("No"); } break; default: rte(); break; } } return 0; }