結果
問題 |
No.430 文字列検索
|
ユーザー |
|
提出日時 | 2021-09-05 04:54:00 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 431 ms / 2,000 ms |
コード長 | 2,871 bytes |
コンパイル時間 | 2,282 ms |
コンパイル使用メモリ | 204,372 KB |
最終ジャッジ日時 | 2025-01-24 08:14:09 |
ジャッジサーバーID (参考情報) |
judge4 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 4 |
other | AC * 14 |
ソースコード
#include <bits/stdc++.h> using namespace std; template<const int char_size> struct Trie_Node{ vector<int> nex, accept; int count; Trie_Node() : count(0){ nex.resize(char_size, -1); } }; template<int char_size, int offset> struct Trie{ private: using Node = Trie_Node<char_size>; vector<Node> Nodes; int root; //文字列の挿入O(|word|) void insert(const string &word, const int str_index){ int now = root; for(int i = 0; i < (int)word.size(); i++){ int id = word[i] - offset; if(Nodes[now].nex[id] == -1){ add(now, id); } ++Nodes[now].count; now = Nodes[now].nex[id]; } ++Nodes[now].count; Nodes[now].accept.push_back(str_index); } void add(int Node_id, int char_id){ Nodes[Node_id].nex[char_id] = (int)Nodes.size(); Nodes.push_back(Node()); } public: Trie() : root(0){ Nodes.push_back(Node()); } void insert(const string &word){ insert(word, Nodes[0].count); } //単語検索O(|word|) int exist(const string &word, bool p = false){ int now = 0; for(int i = 0; i < (int)word.size(); i++){ int temp = word[i] - offset; if(Nodes[now].nex[temp] == -1) return 0; now = Nodes[now].nex[temp]; } if(p) return Nodes[now].count; return (int)Nodes[now].accept.size(); } int prefix(const string &word){ return exist(word, true); } //辞書順に数えてk番目の文字列を出力 O(|word|)(定数倍26)? string kth_string(int k){ assert(k <= count()); string res; int now = 0; int sum = 0; int cnt = 0; while(sum < k){ cnt++; int nxt = -1; for(int i = 0; i < char_size; i++){ int nxt = Nodes[now].nex[i]; if(nxt == -1) continue; int temp = sum + Nodes[nxt].count; if(temp >= k){ res += (char)(offset + i); now = nxt; break; } sum += Nodes[nxt].count; } sum += (int)Nodes[now].accept.size(); } return res; } int count(){ return Nodes[0].count; } int size(){ return (int)Nodes.size(); } }; int main(){ vector<Trie<26, 'A'>> trie(10); string S; cin >> S; int sz = S.size(); for(int i = 1; i <= 10; i++){ for(int j = 0; j + i <= sz; j++){ trie[i - 1].insert(S.substr(j, i)); } } int M; cin >> M; long long sum = 0; for(int i = 0; i < M; i++){ string C; cin >> C; sum += trie[C.size() - 1].prefix(C); } cout << sum << endl; }