1 5 6 orz sto kirigiri danganronpa ooooo o kyouko dangan ronpa ooooo ooooo
1 1 0 3 7
ac自动机模板题啊,直接上模板
#include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<queue> #include<vector> using namespace std; typedef long long ll; const int size = 26;//字典树节点大小 const int base = 'a';//字典树 const int maxn = 100005;//字典树大小(便于各种操作) class tire { public: tire *next[size], *fail; ll cnt, id; //各种节点设置 tire(){ cnt = 0; fail = NULL; memset(next, 0, sizeof(next)); }; };//字典树节点设置 class Ac_machine { private: tire *root;//根节点建立 tire *node[maxn];//与id相对立,便于各种操作 int tot;//字典树大小 char s[maxn];//读入字符串 public: char S[maxn];//母串 Ac_machine(){} void clear(){ node[0] = root = new tire; tot = 0; }//初始化 void insert(int);//插入多个字符串 int insert();//插入字符串,返回字符串大小 void getfail(); //获取失配指针 int getmother();//获得匹配的母串,返回母串大小 int work_out();//求解函数,依照题目不同而不同,返回答案 }ac;//ac自动机设置 int Ac_machine::getmother(){ scanf("%s", S); return strlen(S); } void Ac_machine::insert(int n){ while (n--) insert(); } int Ac_machine::insert() { scanf("%s", s); tire *now = root; for (int i = 0, k; s[i]; i++) { k = s[i] - base; if (!now->next[k]) { node[++tot] = now->next[k] = new tire; now->next[k]->id = tot; } now = now->next[k]; } now->cnt++; //可以插入一些字典树的设置 return strlen(s); } void Ac_machine::getfail() { queue<tire*> p; root->fail = root; for (int i = 0; i < size; i++) if (root->next[i]) { root->next[i]->fail = root; p.push(root->next[i]); } else root->next[i] = root; tire *now; while (!p.empty()) { now = p.front(); p.pop(); now->cnt += now->fail->cnt; //可以插入统计子串个数等操作 for (int i = 0; i < size; i++) if (now->next[i]) { now->next[i]->fail = now->fail->next[i]; p.push(now->next[i]); } else now->next[i] = now->fail->next[i]; } } int Ac_machine::work_out() { ll ans = 0; tire *now = root; //for (int i = 0; i < maxn; i++) printf("%d\n", node[i]->cnt); for (int i = 0, k; S[i]; i++) { k = S[i] - base; now = now->next[k]; ans += now->cnt; } return ans;//返回子串出现次数 } vector<char> p[maxn]; char s[maxn]; int main() { int T,n,m; scanf("%d",&T); while (T--) { ac.clear(); scanf("%d%d",&n,&m); for (int i=1;i<=n;i++) { p[i].clear(); scanf("%s",s); for (int j=0;s[j];j++) p[i].push_back(s[j]); } ac.insert(m); ac.getfail(); for (int i=1;i<=n;i++) { for (int j=0;j<p[i].size();j++) { ac.S[j]=p[i][j]; } ac.S[p[i].size()]=0; printf("%lld\n",ac.work_out()); } } }