字典树的实现(字典树模板)

牛客测试链接:https://www.nowcoder.com/practice/7f8a8553ddbf4eaab749ec988726702b

#include <bits/stdc++.h>
using namespace std;
const int N=2e5+10;
typedef long long ll;
int t,n;
int m;
string s;
int tree[N][26];
int pass[N];
int ed[N];
int cnt=1;



void insert(string word)
{
    int cur=1;
    pass[cur]++;
    for(int i=0,path;i<word.size();i++)
    {
        path = word[i]-'a';
        if(tree[cur][path]==0)
        {
            tree[cur][path]=++cnt;
        }
        cur = tree[cur][path];
        pass[cur]++;
    }
    ed[cur]++;
}

int search(string word)
{
    int cur=1;
    for(int i=0,path;i<word.size();i++)
    {
        path = word[i]-'a';
        if(tree[cur][path]==0)return 0;
        cur = tree[cur][path];
    }
    return ed[cur];
    
}


int prefixnum(string pre)
{
    int cur=1;
    for(int i=0,path;i<pre.size();i++)
    {
        path = pre[i]-'a';
        if(tree[cur][path]==0)return 0;
        cur = tree[cur][path];

    }
    return pass[cur];
}

void del(string word)
{

    if(search(word)>0)
    {
        int cur=1;
        pass[cur]--;
        for(int i=0,path;i<word.size();i++)
        {
            path = word[i]-'a';
            if(--pass[tree[cur][path]]==0)
            {
                tree[cur][path]=0;
                return;
            }
            cur = tree[cur][path];
        }
        ed[cur]--;
    }
}





int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin>>m;
    while(m--)
    {
        int op;
        cin>>op;
        cin>>s;

        if(op==1)
        {
            insert(s);
        }
        else if(op==2)
        {
            del(s);
        }
        else if(op==3)
        {
            if(search(s))
            {
                cout<<"YES"<<endl;
            }
            else cout<<"NO"<<endl;
        }
        else
        {
            cout<<prefixnum(s)<<endl;
        }
        
    }
    return 0;
}

洛谷的模板难度相对来说更小,只需要插入和计算前缀数量的操作
洛谷测试链接:https://www.luogu.com.cn/problem/P8306

#include <bits/stdc++.h>
using namespace std;
const int N=3e6+10;
typedef long long ll;
int t,n,q;
int tree[N][65];
int pass[N];
int cnt;
string s;

void insert(string word)
{
    int cur=1;
    pass[cur]++;
    for(int i=0,path;i<word.size();i++)
    {
        if(word[i]>='a'&&word[i]<='z')path = word[i]-'a';
        else if(word[i]>='A'&&word[i]<='Z')path=word[i]-'A'+26;
        else if(word[i]>='0'&&word[i]<='9')path=word[i]-'0'+52;
        if(tree[cur][path]==0)tree[cur][path]=++cnt;
        cur = tree[cur][path];
        pass[cur]++;
    }
}

int prefixnum(string word)
{
    int cur=1;
    for(int i=0,path;i<word.size();i++)
    {
        if(word[i]>='a'&&word[i]<='z')path = word[i]-'a';
        else if(word[i]>='A'&&word[i]<='Z')path=word[i]-'A'+26;
        else if(word[i]>='0'&&word[i]<='9')path=word[i]-'0'+52;
        if(tree[cur][path]==0)return 0;
        cur = tree[cur][path];
    }
    return pass[cur];
}





int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin>>t;
    
    while(t--)
    {

        cnt=1;
        
        cin>>n>>q;
        for(int i=0;i<n;i++)
        {
            cin>>s;
            insert(s);
        }
        for(int i=0;i<q;i++)
        {
            cin>>s;
            cout<<prefixnum(s)<<endl;
        }
        for(int i=1;i<=cnt;i++)
        {
            for(int j=0;j<65;j++)tree[i][j]=0;
            pass[i]=0;
            
        }

    }
    return 0;
}
posted @ 2025-06-17 13:31  屈臣  阅读(11)  评论(0)    收藏  举报