/*==================================================*\
[Trie] 字典树
support:
- insert O(L)
- query O(L)
- delete O(L)
Trie[i]存储第i个节点的信息:
next[j]: 下一个字符为j时 对应的节点编号
fa: 父亲节点编号
cnt: 字符出现次数
\*==================================================*/
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>
#include <map>
#include <set>
#include <string>
using namespace std;
//----------------------------------------------
#define CL(a,num) memset(a,num,sizeof(a));
#define BtoA(x,y) memcpy(x,y,sizeof(x));
#define eps 1e-12
#define inf 0x7fffffff
typedef __int64 LL;
//----------------------------------------------
const int Node_max = 100000 + 5;
struct Node {
int next[26];
// including a...z
int fa, cnt, flag;
} Trie[Node_max];
// root = Trie[0]
int Trie_size;
#define t_s Trie_size
int Trie_ins(char str[]) {
int len = strlen(str);
int tmp = 0;
for(int i = 0; i < len; ++i) {
if(!Trie[tmp].next[str[i] - 'a']) {
Trie[tmp].next[str[i] - 'a'] = ++t_s;
Trie[t_s].fa = tmp;
}
tmp = Trie[tmp].next[str[i] - 'a'];
}
return ++Trie[tmp].cnt;
// let the appear_times of str increase then return it
}
int Trie_query(char str[]) {
//return the appear_times of str
int len = strlen(str);
int tmp = 0;
for(int i = 0; i < len; ++i) {
if(!Trie[tmp].next[str[i] - 'a'])
return -1; // if can't find str
tmp = Trie[tmp].next[str[i] - 'a'];
}
return Trie[tmp].cnt;
}
int Trie_del(char str[]) {
int len = strlen(str);
int tmp = 0;
for(int i = 0; i < len; ++i) {
if(!Trie[tmp].next[str[i] - 'a'])
return -1; // if can't find str
tmp = Trie[tmp].next[str[i] - 'a'];
}
return --Trie[tmp].cnt;
// let the appear_times of str decrease then return it
}
int main() {
char str[20];
while(true) {
int op;
cin >> op;
switch(op) {
case 0: //ins
cin >> str;
cout << Trie_ins(str) << endl;
break;
case 1: //query
cin >> str;
cout << Trie_query(str) << endl;
break;
case 2: //del
cin >> str;
cout << Trie_del(str) << endl;
break;
}
}
return 0;
}