原帖链接

我是这么理解 idx 的,每进来一个新的之前没有的节点,idx就++ ,这个idx 就代表了这个这个节点,然后这个idx赋给了这个 p,再向下查找,cnt[p]就也是这个节点出现次数增加。
#include<bits/stdc++.h>
using namespace std;
int T,q,n;
int idx;//每进来一个新的之前没有的节点,idx就++ ,
//这个idx 就代表了这个这个节点,然后这个idx赋给了这个 p,
//再向下查找,cnt[p]就也是这个节点出现次数增加。
int t[3000005][65];//字典树的框架
int cnt[3000005];//这个字符出现的个数,因为这题要求求出前缀个数
char s[3000005];//储存字符串
//识别字符
int getnum(char x){
if(x>='A'&&x<='Z')
return x-'A';
else if(x>='a'&&x<='z')
return x-'a'+26;
else
return x-'0'+52;
}
void insert(string str){
int p=0,len=str.size();
for(int i=0;i<len;i++){
int c=getnum(str[i]);//获得第几个儿子的编号
if(t[p][c]==0)//如果没有就新建节点
t[p][c]=++idx;//第几个节点,赋值一个独有的编号
p=t[p][c];//到下一个节点
cnt[p]++;//出现次数增加
}
}
int find(string str){
int p=0,len=str.size();
for(int i=0;i<len;i++){
int c=getnum(str[i]);//获得第几个儿子的编号
if(!t[p][c])//没有这个节点,返回0;
return 0;
p=t[p][c];//到下一个节点
}
return cnt[p];//最后这个字符出现次数也是这个前缀出现的次数
}
void solve(){
cin>>n>>q;
idx=0;
for(int i=1;i<=n;i++){
cin>>s;
insert(s);
}
for(int i=1;i<=q;i++){
cin>>s;
cout<<find(s)<<"\n";
}
}
int main(){
ios::sync_with_stdio(0);
cin.tie(nullptr);
int T;
cin>>T;
while(T--){
//初始化
for(int i=0;i<=idx;i++){
for(int j=0;j<=64;j++){
t[i][j]=0;
}
cnt[i]=0;
}
solve();
}
return 0;
}