字典树

字典树模板题

原帖链接

字典树

我是这么理解 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;
}
posted @ 2025-10-21 00:36  sad_lin  阅读(5)  评论(0)    收藏  举报