constint N = 1e5 + 10; // 因为是只有小写字母,所以第二维度的值为26 // cnt 表示以某一个节点结尾的个数有多少个 // idx为下标的使用情况, 题目规定所有字符串的总长度是10^5 int son[N][26], cnt[N], idx; char str[N];
// 插入操作 voidinsert(char *str){ int p = 0; for(int i = 0; str[i]; i++) { int u = str[i] - 'a'; if (!son[p][u]) son[p][u] = ++idx; p = son[p][u]; } cnt[p]++; }
// 查询操作 intquery(char *str){ int p = 0; for(int i = 0; str[i]; i++) { int u = str[i] - 'a'; if (!son[p][u]) return0; p = son[p][u]; } return cnt[p]; }
intmain(){ int n; cin >> n; while(n--) { string op; cin >> op >> str; if (op == "I") insert(str); elseprintf("%d\n", query(str)); } return0; }
// M 表示节点个数, N = 10^5, Ai = 31 位数 constint N = 1e5 + 10, M = 3e6 + 10;
// idx 表示节点的使用情况 int son[M][2], idx; int a[N], n;
// 如果有节点就往下走,没有就创建出来继续往下走 voidinsert(int x){ int p = 0; for(int i = 30; ~i; i--) { int &s = son[p][x >> i & 1]; if (!s) s = ++idx; p = s; } }
// 查询 // 当某一个节点有异或值得时候,那么加上该位的值,res += 1 >> i; 没有就是 res += 0 >> i, 这里等于0 所以省略掉 intquery(int x){ int p = 0, res = 0; for(int i = 30; ~i; i--) { int s = x >> i & 1; if (son[p][!s]) { res += 1 << i; p = son[p][!s]; } else p = son[p][s]; } return res; }