辞書ツリー p8036

説明

�n 個のパターン文字列�1,�2,…,�s1�,s2�,…,sn�および�q クエリが与えられた場合、各クエリにはテキスト文字列�ti�が与えられます。�1 文字列の数�を答えてください。 ��sj は、��ti が��sj の接頭語となるように、∼��s1��∼sn に存在します

文字列 �t は、�s の末尾からいくつかの (おそらく 0 個の) 連続文字を削除した後、�t と同じである場合に限り、�s の接頭辞になります。

入力文字列のサイズは重要です。たとえば、文字列 Fusu と文字列 fusu は異なります。

入力

この問題集のテストポイントには複数のテストデータが含まれています

入力の最初の行は、データセット数 �T を表す整数です。

データの各セットの形式は次のとおりです。
最初の行は 2 つの整数で、それぞれパターン文字列の数 �n とクエリの数 �q を表します。
次の �n 行には、各行にパターン文字列を表す文字列が含まれています。
次の �q 行はそれぞれ文字列を含み、クエリを表します。

出力

各テストデータの回答は入力順に出力されます。
クエリごとに、答えを表す整数を含む行を出力します。

サンプル1

入力コピー 出力コピー
3
3 3
fusufusu
戦い
怒っている
戦い
怒っている
kkksc
5 2
戦い
戦い
AFakeFusu
afakefusu
ふすいではない偽物
戦い
戦い
1 1
998244353
9
2
1
0
1
2
1

ヒント

データのサイズと規則

すべてのテスト ポイントについて、1≤�,�,�≤1051≤T,n,q≤105 であり、入力文字列の合計長が 3×1063×106 を超えないことが保証されます。入力文字列には大文字、小文字、数字のみが含まれ、空の文字列は含まれません。

説明する

同期がオフになった後、std の IO は cin/cout を使用します。この質問はスタックしていません。

#include<bits/stdc++.h>
名前空間 std を使用します。
const int N=3e6+10;
int tr[N][100];
int idx=0;
int cnt[N];
int change(char x){     if(x<='z'&&x>='a')return x-'a';     else if(x<='Z'&&x>='A')return x-'A'+26;     それ以外の場合は x-'0'+52 を返します。void insert(string b){     int u=0;     for(int i=0;i<b.size();i++){         int j=change(b[i]);         if(!tr[u][j]){             idx++;             tr[u][j]=idx;         u         =tr[u][j];         cnt[u]++;     } }











            

    



int search(string b){     int u=0;     for(int i=0;b[i];i++){//b[i] == i<b.size()         int j=change(b[i]);         if(!tr[u][j]){             0 を返す;         u         =tr[u][j];     cnt[u]を返します     ; void sol(){     for(int i=0;i<=idx;i++){ memset         (tr[i],0,sizeof(tr[i]));         cnt[i]=0;     idx     =0;     int n,q;cin>>n>>q;         文字列 a;     while(n--){         cin>>a;         挿入(a);     }      while(q--){         cin>>a;         cout<<search(a)<<endl;


























int
main(){     int     t;cin>>t;     while(t--)sol();     0を返します。}



おすすめ

転載: blog.csdn.net/m0_74310050/article/details/130295902