int son[N][26], cnt[N], idx;//idx 当前用到了的结点的下标 // 0号点既是根节点,又是空节点// son[][]存储树中每个节点的子节点// cnt[]存储以每个节点结尾的单词数量// 插入一个字符串voidinsert(char*str){int p =0;for(int i =0; str[i]; i ++){int u = str[i]-'a';// u代表 a ~ 字母 p代表下标 if(!son[p][u]) son[p][u]=++ idx;//如果 p结点不存在 u这个儿子的话,就创建出来
p = son[p][u];//son[]数组里存的是下标 是下一个结点的下标 }
cnt[p]++;//从 root 下来第 p个结点处存在的单词数+1 }// 查询字符串出现的次数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];//插入时就已经设置了 son[]的值 (是下一个结点的下标) }return cnt[p];//找到这个单词,输出这个单词在集合中出现的次数 }
完整题解
#include<bits/stdc++.h>
using namespace std;#define N 100010int son[N][26], cnt[N], idx;//idx 当前用到了的结点的下标 // 0号点既是根节点,又是空节点// son[][]存储树中每个节点的子节点// cnt[]存储以每个节点结尾的单词数量// 插入一个字符串voidinsert(char*str){int p =0;for(int i =0; str[i]; i ++){int u = str[i]-'a';// u代表 a ~ 字母 p代表下标 if(!son[p][u]) son[p][u]=++ idx;//如果 p结点不存在 u这个儿子的话,就创建出来
p = son[p][u];//son[]数组里存的是下标 是下一个结点的下标 }
cnt[p]++;//从 root 下来第 p个结点处存在的单词数+1 }// 查询字符串出现的次数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];//插入时就已经设置了 son[]的值 (是下一个结点的下标) }return cnt[p];//找到这个单词,输出这个单词在集合中出现的次数 }intmain(){int n;
cin>>n;for(int i=1; i<=n; i++){char a;char b[100010];
cin >> a;
cin >> b;if(a =='I')insert(b);elseprintf("%d\n",query(b));}return0;}