給定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行每行輸入乙個...