#ifndef LOCAL #pragma GCC target("arch=x86-64-v3") // judge: v4 or cascadelake(←最後の一投で試すレベルでv4と差がないと思ってる) #pragma GCC optimize("Ofast") #endif #include using namespace std; using i64 = long long; struct Trie{ vector> ch; vector slink, depth; Trie() : ch(1), depth(1, 0){} int add(int idx, char c){ auto it = ch[idx].find(c); if(it == ch[idx].end()){ ch.emplace_back(); depth.emplace_back(depth[idx] + 1); return ch[idx][c] = ch.size() - 1; } return it->second; } int insert(string s){ int idx = 0; for(auto c : s){ idx = add(idx, c); } return idx; } void build(){ slink.resize(ch.size(), 0); queue que; for(auto [_, k] : ch[0]){ slink[k] = 0; que.emplace(k); } while(!que.empty()){ int x = que.front(); que.pop(); for(auto [c, y] : ch[x]){ int xx = slink[x]; while(xx && ch[xx].find(c) == ch[xx].end())xx = slink[xx]; auto it = ch[xx].find(c); slink[y] = it == ch[xx].end() ? 0 : it->second; que.emplace(y); } } } vector search(string s){ vector idxes(s.size() + 1, 0); int idx = 0; for (int i = 0; i < s.size(); ++i) { while(idx && ch[idx].find(s[i]) == ch[idx].end())idx = slink[idx]; auto it = ch[idx].find(s[i]); if(it != ch[idx].end())idx = it->second; idxes[i + 1] = idx; } return idxes; // array of maximal reach length } }; bool solve(){ string s; int m; cin >> s >> m; vector t(m); for(int i = 0; i < m; ++i){ cin >> t[i]; } Trie trie; vector v; for(int i = 0; i < m; ++i){ v.emplace_back(trie.insert(t[i])); } trie.build(); auto res = trie.search(s); vector> edges(trie.ch.size()); queue que; que.emplace(0); vector tps; while(!que.empty()){ int x = que.front(); que.pop(); tps.emplace_back(x); if(x){ edges[trie.slink[x]].emplace_back(x); } for(auto [c, y] : trie.ch[x]){ que.emplace(y); } } vector w(trie.ch.size()); for(auto x : v)++w[x]; for(auto x : tps){ for(auto y : edges[x]){ w[y] += w[x]; } } i64 ans = 0; for(auto x : res){ ans += w[x]; } cout << ans << endl; return 0; } signed main(){ // cin.tie(0); // cin.sync_with_stdio(0); solve(); exit(0); int t; cin >> t; while(t --> 0){ solve(); } }