結果
問題 | No.430 文字列検索 |
ユーザー | veqcc |
提出日時 | 2019-07-17 17:32:41 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 13 ms / 2,000 ms |
コード長 | 3,493 bytes |
コンパイル時間 | 795 ms |
コンパイル使用メモリ | 76,588 KB |
実行使用メモリ | 7,448 KB |
最終ジャッジ日時 | 2024-11-10 00:26:40 |
合計ジャッジ時間 | 1,462 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge4 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
5,248 KB |
testcase_01 | AC | 10 ms
7,448 KB |
testcase_02 | AC | 8 ms
5,248 KB |
testcase_03 | AC | 6 ms
5,248 KB |
testcase_04 | AC | 2 ms
5,248 KB |
testcase_05 | AC | 2 ms
5,248 KB |
testcase_06 | AC | 2 ms
5,248 KB |
testcase_07 | AC | 2 ms
5,248 KB |
testcase_08 | AC | 4 ms
5,248 KB |
testcase_09 | AC | 2 ms
5,248 KB |
testcase_10 | AC | 2 ms
5,248 KB |
testcase_11 | AC | 13 ms
6,060 KB |
testcase_12 | AC | 13 ms
6,564 KB |
testcase_13 | AC | 13 ms
6,560 KB |
testcase_14 | AC | 10 ms
5,692 KB |
testcase_15 | AC | 9 ms
5,688 KB |
testcase_16 | AC | 9 ms
5,560 KB |
testcase_17 | AC | 9 ms
5,564 KB |
ソースコード
#include <iostream> #include <vector> using namespace std; // TrieNode // count: このnode以下にいくつ単語が格納されているか // accept: このnodeでぴったりのものindexの集合 // Trie // プレフィックス木とも。ルートには空文字が対応 // add(s, str_i, node_i, id) // sをTrieに追加する // 計算量は O(|S|) // query(s, fun, str_i, node_i) // sをi文字目から読んでいき、それに沿ってTrie木をたどる。 // たどるNodeごとに、関数funを適用する。 // 計算量は O(|S|) template <int char_size> struct TrieNode { int count; vector <int> nxt, accept; TrieNode() : count(0) { nxt.assign(char_size + 1, -1); } }; template <int char_size, int base> class Trie { using Node = TrieNode <char_size>; vector <Node> nodes; void add(const string &s, int str_i, int node_i, int id) { if (str_i == s.size()) { nodes[node_i].accept.push_back(id); } else { const int c = s[str_i] - base; if (nodes[node_i].nxt[c] == -1) { nodes[node_i].nxt[c] = nodes.size(); nodes.push_back(Node()); } add(s, str_i + 1, nodes[node_i].nxt[c], id); nodes[node_i].count++; } } public: Trie() { nodes.push_back(Node()); } void add(const string &s) { add(s, 0, 0, nodes[0].count); } // yukicoderでは std::function で CE してしまう(原因不明) // void query(const string &s, const function<void(int)> &f, int str_i, int node_i) { // for (auto &idx : nodes[node_i].accept) f(idx); // if (str_i < s.size()) { // const int c = s[str_i] - base; // if (nodes[node_i].nxt[c] >= 0) { // query(s, f, str_i + 1, nodes[node_i].nxt[c]); // } // } // } int enumerate(const string &s, int str_i, int node_i) { int ret = nodes[node_i].accept.size(); if (str_i < s.size()) { const int c = s[str_i] - base; if (nodes[node_i].nxt[c] >= 0) { ret += enumerate(s, str_i + 1, nodes[node_i].nxt[c]); } } return ret; } }; // verified // https://tenka1-2016-final-open.contest.atcoder.jp/tasks/tenka1_2016_final_c //void AtCoder_2016_9_10_C() { // string s; // cin >> s; // // int m; // cin >> m; // // Trie<26, 'a'> trie; // // string p[5005]; // for (int i = 0; i < m; i++) { // cin >> p[i]; // trie.add(p[i]); // } // // int w[5005]; // for (int i = 0; i < m; i++) { // cin >> w[i]; // } // // int sz = s.size(); // vector <int> dp(sz + 1); // for (int i = 0; i < sz; i++) { // auto update = [&](int idx) { // dp[i + p[idx].size()] = max(dp[i + p[idx].size()], dp[i] + w[idx]); // }; // trie.query(s, update, i, 0); // dp[i + 1] = max(dp[i + 1], dp[i]); // } // // cout << dp.back() << "\n"; //} // verified // https://yukicoder.me/problems/no/430 void yuki_430() { string s; int m; cin >> s >> m; Trie<26, 'A'> trie; string c[5005]; for (int i = 0; i < m; i++) { cin >> c[i]; trie.add(c[i]); } int ans = 0; for (int i = 0; i < s.size(); i++) { ans += trie.enumerate(s, i, 0); } cout << ans << '\n'; } int main() { // AtCoder_2016_9_10_C(); yuki_430(); return 0; }