F06【模板】字典树(Trie)
题目:一个文本串是多少模式串的前缀
把所有模式串插入字典树,
字典树上的一条边代表一个字符,一个节点代表一个字符串前缀,
节点标记前缀出现次数。
// 字典树 O(n) #include<bits/stdc++.h> using namespace std; const int N=3e6+5; int T,n,q; int ch[N][65],cnt[N],idx; //ch[p][i]:点边数组,对应多叉树 int getnum(char c){ if(c>='A'&&c<='Z') return c-'A'; //0~25 else if(c>='a'&&c<='z') return c-'a'+26; //26~51 else return c-'0'+52; //52~61 } void insert(string s){ int p=0; for(auto c:s){ int i=getnum(c); if(!ch[p][i]) ch[p][i]=++idx; //从p点走边i到达新点的编号 p=ch[p][i]; //走到子节点 cnt[p]++; //p点之前的前缀的插入次数 } } int query(string s){ int p=0; for(auto c:s){ int i=getnum(c); if(!ch[p][i]) return 0; p=ch[p][i]; } return cnt[p]; } int main(){ ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); cin>>T; while(T--){ cin>>n>>q; string s; for(int i=1;i<=n;i++) cin>>s,insert(s); for(int i=1;i<=q;i++) cin>>s,cout<<query(s)<<"\n"; for(int i=0;i<=idx;i++) for(int j=0;j<65;j++) ch[i][j]=0; for(int i=0;i<=idx;i++) cnt[i]=0; idx=0; } return 0; }
// 哈希法 O(n) #include<bits/stdc++.h> using namespace std; typedef unsigned long long ull; const int B=131; int n,q; string str; unordered_map<ull,int> f; signed main(){ ios::sync_with_stdio(0);cin.tie(0); cout.tie(0); int T; cin>>T; while(T--){ cin>>n>>q; f.clear(); for(int i=1; i<=n; ++i){ cin>>str; ull h=0; for(auto j:str) h=h*B+j,f[h]++; //f:前缀哈希值的出现次数 } while(q--){ cin>>str; ull h=0; for(auto i:str) h=h*B+i; cout<<f[h]<<'\n'; } } return 0; }
AT_agc057_c [AGC057C] Increment or Xor - 洛谷
浙公网安备 33010602011771号