結果
問題 | No.430 文字列検索 |
ユーザー | veqcc |
提出日時 | 2019-07-23 18:17:10 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 12 ms / 2,000 ms |
コード長 | 3,017 bytes |
コンパイル時間 | 944 ms |
コンパイル使用メモリ | 84,812 KB |
実行使用メモリ | 7,580 KB |
最終ジャッジ日時 | 2024-11-10 00:26:47 |
合計ジャッジ時間 | 1,585 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 1 ms
5,248 KB |
testcase_01 | AC | 10 ms
7,580 KB |
testcase_02 | AC | 6 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 | 3 ms
5,248 KB |
testcase_09 | AC | 2 ms
5,248 KB |
testcase_10 | AC | 2 ms
5,248 KB |
testcase_11 | AC | 12 ms
6,064 KB |
testcase_12 | AC | 11 ms
6,560 KB |
testcase_13 | AC | 12 ms
6,560 KB |
testcase_14 | AC | 10 ms
5,692 KB |
testcase_15 | AC | 8 ms
5,560 KB |
testcase_16 | AC | 8 ms
5,688 KB |
testcase_17 | AC | 8 ms
5,560 KB |
ソースコード
#include <functional> #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); } 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]); } } } }; // verified // https://tenka1-2016-final-open.contest.atcoder.jp/tasks/tenka1_2016_final_c void AtCoder_2016_9_10_C() { string s; int m; cin >> s >> 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++) { auto update = [&](int idx) { ans++; }; trie.query(s, update, i, 0); } cout << ans << '\n'; } int main() { // AtCoder_2016_9_10_C(); yuki_430(); return 0; }