#include #include #include #include #include using namespace std; const int alpha = 26;//alphabet_size struct AhoCorasick{ int sumLength = 0;//sum of |P_i| + 1 vector pattern; vector> Trie; vector failureLink; vector isEnd; vector trulyFailureLink,dist; // it is not used for counting but used for enumerating vector> failureTree; // it is not used for enumerating but used for counting AhoCorasick(vector &P){ createTrie(P); createFailureLink(); createTrulyFailureLink(); createFailureTree(); } //make Trie void createTrie(vector &P){ pattern = P; sumLength = 1; for(string str:pattern) sumLength += str.size(); Trie.resize(sumLength + 1); isEnd.resize(sumLength + 1); int index = 1; int maxPosition = 1; for(string str:pattern){ int position = 1; //the index of root = 1; int latestEnd = 1; for(char chr:str){ if(!Trie[position][chr - 'A']) Trie[position][chr - 'A'] = ++maxPosition; position = Trie[position][chr - 'A']; } isEnd[position] = index++; } } //make failureLink void createFailureLink(){ failureLink.resize(sumLength + 1); dist.resize(sumLength + 1); failureLink[1] = 1; queue> bfsQue; bfsQue.push({1,0}); while(bfsQue.size()){ int position = bfsQue.front().first; dist[position] = bfsQue.front().second; bfsQue.pop(); for(int i=0;i bfsQue; bfsQue.push(1); while(bfsQue.size()){ int position = bfsQue.front(); bfsQue.pop(); if(position!=1){ if(isEnd[failureLink[position]]) trulyFailureLink[position] = failureLink[position]; else trulyFailureLink[position] = trulyFailureLink[failureLink[position]]; }else{ trulyFailureLink[position] = 1; } for(int i=0;i> enumerate(string S){ S.push_back('z' + 1); vector> enume(pattern.size()); int position = 1; int left = 0; for(char chr:S){ while(position!=1 && !(chr - 'A' cnt; void dfs_cnt(int pos){ if(pos==0) exit(1); for(int nextPos:failureTree[pos]){ dfs_cnt(nextPos); cnt[pos] += cnt[nextPos]; } } // sにいくつpatternが存在するか数える vector countPattern(string S){ cnt.resize(sumLength + 1); S.push_back('z' + 1); //記事中の7の代用 int position = 1; for(char chr:S){ while(position!=1 && !(chr - 'A' resultOfCount(pattern.size()); for(int i=1;i<=sumLength;i++){ if(isEnd[i]){ resultOfCount[isEnd[i] - 1] = cnt[i];// 1引くことに注意 } } return resultOfCount; } void debugAhoCora(){ for(int i=0;i> s; int i,m; cin >> m; vector t(m); for(i=0;i> t[i]; AhoCorasick aho(t); int ans = 0; vector> enu = aho.enumerate(s); vector cnt = aho.countPattern(s); for(i=0;i