Acwing 142 字首統計

2021-10-02 12:47:13 字數 2038 閱讀 5396

給定n個字串s1,s2…sn,接下來進行m次詢問,每次詢問給定乙個字串t,求s1~sn

中有多少個字串是t的字首。

輸入字串的總長度不超過106

,僅包含小寫字母。

輸入格式

第一行輸入兩個整數n,m。

接下來n行每行輸入乙個字串si

接下來m行每行乙個字串t用以詢問。

輸出格式

對於每個詢問,輸出乙個整數表示答案。

每個答案佔一行。

輸入樣例:

3 2

abbc

abcabc

efg

輸出樣例:

2

0

這裡再次複習下字典樹。

下面我們來講一下對於給定的字串集合如何建立對應的trie樹。其實上trie樹的建立是從只有根節點開始,通過依次將w1, w2, w3, … wn插入trie中實現的。所以關鍵就是之前提到的trie的插入操作。

具體來說,trie一般支援兩個操作:

1. trie.insert(w):第乙個操作是插入操作,就是將乙個字串w加入到集合中。

2. trie.search(s):第二個操作是查詢操作,就是查詢乙個字串s是不是在集合中。

假設我們要插入字串」in」。我們一開始位於根,也就是0號節點,我們用p=0表示。我們先看p是不是有一條標識著i的連向子節點的邊。沒有這條邊,於是我們就新建乙個節點,也就是1號節點,然後把1號節點設定為p也就是0號節點的子節點,並且將邊標識為i。最後我們移動到1號節點,也就是令p=1。

這樣我們就把」in」的i字元插入到trie中了。然後我們再插入字元n,也是先找p也就是1號節點有沒有標記為n的邊。還是沒有,於是再新建乙個節點2,設定為p也就是1號節點的子節點,並且把邊標識為n。最後再移動到p=2。這樣我們就把n也插入了。由於n是」in」的最後乙個字元,所以我們還需要將p=2這個節點標記為終結點。

現在我們再插入字串」inn」。過程也是一樣的,從p=0開始找標識為i的邊,這次找到1號節點。於是我們就不用建立新節點了,直接移動到1號節點,也就是令p=1。再插入字元n,也是有2號節點存在,所以移動到2號節點,p=2。最後再插入字元n這時p沒有標識為n的邊了,所以新建3號節點作為2號節點的子節點,邊標識為n,同時將3號節點標記為終結點:

將後面的字串int tea ten to都插入之後,就得到了我們一開始給出的trie:

這裡用乙個二維陣列來表示trie,int son[maxn][26];

int idx;

其中maxn是trie中最大能儲存的節點數目,26是字符集的大小,idx是當前trie中包含有多少個節點。son[i][j]的值是0表示trie樹中i號節點,並沒有一條連出去的邊,滿足邊上的字元標識是字符集中第j個字元(從0開始);son[i][j]的值是正整數x表示trie樹中i號節點,有一條連出去的邊,滿足邊上的字元標識是字符集中第j個字元,並且這條邊的終點是x號節點。

#include#includeusing namespace std;

const int maxn = 1e6+10;

char str[maxn];

int son[maxn][26],cnt[maxn],idx;

int n,m;

void insert()

cnt[p]++;

}int query()

return res;

}int main()

while(m--)

}

參考文章:

AcWing 142 字首統計

題目描述 給定n個字串s1,s2 sn,接下來進行m次詢問,每次詢問給定乙個字串t,求s1 sn中有多少個字串是t的字首。輸入字串的總長度不超過106,僅包含小寫字母。輸入格式 第一行輸入兩個整數n,m。接下來n行每行輸入乙個字串si。接下來m行每行乙個字串t用以詢問。輸出格式 對於每個詢問,輸出乙...

acwing 142 字首統計 字典樹

給定n個字串s1,s2 sn,接下來進行m次詢問,每次詢問給定乙個字串t,求s1 sn中有多少個字串是t的字首。輸入字串的總長度不超過106,僅包含小寫字母。輸入格式 第一行輸入兩個整數n,m。接下來n行每行輸入乙個字串si。接下來m行每行乙個字串t用以詢問。輸出格式 對於每個詢問,輸出乙個整數表示...

AcWing 142 字首統計(字典樹)

給定n個字串s1,s2 s n s1,s2 sn s1,s2 sn,接下來進行m次詢問,每次詢問給定乙個字串t,求s 1 s1 s1 s n sn sn中有多少個字串是t的字首。輸入字串的總長度不超過10 6 106 106,僅包含小寫字母。輸入格式 第一行輸入兩個整數n,m。接下來n行每行輸入乙個...