1. 程式人生 > >CH 1601 - 字首統計 - [字典樹模板題]

CH 1601 - 字首統計 - [字典樹模板題]

題目連結:傳送門

描述
給定 $N$ 個字串 $S_1,S_2,\cdots,S_N$,接下來進行 $M$ 次詢問,每次詢問給定一個字串 $T$,求 $S_1 \sim S_N$ 中有多少個字串是 $T$ 的字首。輸入字串的總長度不超過 $10^6$,僅包含小寫字母。

輸入格式
第一行兩個整數 $N,M$。接下來 $N$ 行每行一個字串 $S_i$。接下來 $M$ 行每行一個字串表示詢問。

輸出格式
對於每個詢問,輸出一個整數表示答案

樣例輸入
3 2
ab
bc
abc
abc
efg
樣例輸出
2
0

 

模板(一個最最普通的字典樹模板):

namespace Trie
{
    
const int SIZE=1e6+10; int sz; struct TrieNode { int ed; int nxt[26]; }trie[SIZE]; void init() { sz=1; for(int i=0;i<SIZE;i++) { trie[i].ed=0; memset(trie[i].nxt,0,sizeof(trie[i].nxt)); } } void insert(string
s) { int p=1; for(int i=0;i<s.size();i++) { int ch=s[i]-'a'; if(trie[p].nxt[ch]==0) trie[p].nxt[ch]=++sz; p=trie[p].nxt[ch]; } trie[p].ed++; } bool search(string s) { int p=1; for(int i=0;i<s.size();i++) { p
=trie[p].nxt[s[i]-'a']; if(!p) return 0; } return trie[p].ed; } };
View Code

 

題解:

字典樹板子題,對上面的板子稍作修改即可。

 

AC程式碼:

#include<bits/stdc++.h>
using namespace std;

namespace Trie
{
    const int SIZE=1e6+10;
    int sz;
    struct TrieNode
    {
        int ed;
        int nxt[26];
    }trie[SIZE];
    void init()
    {
        sz=1;
        for(int i=0;i<SIZE;i++)
        {
            trie[i].ed=0;
            memset(trie[i].nxt,0,sizeof(trie[i].nxt));
        }
    }
    void insert(string s)
    {
        int p=1;
        for(int i=0;i<s.size();i++)
        {
            int ch=s[i]-'a';
            if(trie[p].nxt[ch]==0) trie[p].nxt[ch]=++sz;
            p=trie[p].nxt[ch];
        }
        trie[p].ed++;
    }
    int search(string s)
    {
        int res=0;
        int p=1;
        for(int i=0;i<s.size();i++)
        {
            p=trie[p].nxt[s[i]-'a'];
            res+=trie[p].ed;
            if(!p) return res;
        }
        return res;
    }
};
int n,m;
string s;
int main()
{
    cin>>n>>m;
    Trie::init();
    for(int i=1;i<=n;i++)
    {
        cin>>s;
        Trie::insert(s);
    }
    for(int i=1;i<=m;i++)
    {
        cin>>s;
        cout<<Trie::search(s)<<endl;
    }
}