結果
問題 | No.430 文字列検索 |
ユーザー | ixmel |
提出日時 | 2017-11-24 17:23:47 |
言語 | C++11 (gcc 11.4.0) |
結果 |
AC
|
実行時間 | 14 ms / 2,000 ms |
コード長 | 4,031 bytes |
コンパイル時間 | 973 ms |
コンパイル使用メモリ | 103,224 KB |
実行使用メモリ | 7,816 KB |
最終ジャッジ日時 | 2024-11-10 00:18:27 |
合計ジャッジ時間 | 1,627 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
5,248 KB |
testcase_01 | AC | 14 ms
7,816 KB |
testcase_02 | AC | 6 ms
5,248 KB |
testcase_03 | AC | 6 ms
5,248 KB |
testcase_04 | AC | 1 ms
5,248 KB |
testcase_05 | AC | 2 ms
5,248 KB |
testcase_06 | AC | 1 ms
5,248 KB |
testcase_07 | AC | 1 ms
5,248 KB |
testcase_08 | AC | 3 ms
5,248 KB |
testcase_09 | AC | 2 ms
5,248 KB |
testcase_10 | AC | 1 ms
5,248 KB |
testcase_11 | AC | 10 ms
5,740 KB |
testcase_12 | AC | 10 ms
5,892 KB |
testcase_13 | AC | 10 ms
5,900 KB |
testcase_14 | AC | 9 ms
5,736 KB |
testcase_15 | AC | 8 ms
5,604 KB |
testcase_16 | AC | 7 ms
5,736 KB |
testcase_17 | AC | 7 ms
5,736 KB |
ソースコード
#include<iostream> #include<vector> #include<string> #include<algorithm> #include<map> #include<set> #include<utility> #include<cmath> #include<cstring> #include<queue> #include<stack> #include<cstdio> #include<sstream> #include<iomanip> #include<assert.h> #include<typeinfo> #define loop(i,a,b) for(int i=a;i<b;i++) #define rep(i,a) loop(i,0,a) #define pb push_back #define all(in) in.begin(),in.end() #define shosu(x) fixed<<setprecision(x) using namespace std; //kaewasuretyuui typedef long long ll; //#define int ll typedef int Def; typedef pair<Def,Def> pii; typedef vector<Def> vi; typedef vector<vi> vvi; typedef vector<pii> vp; typedef vector<vp> vvp; typedef vector<string> vs; typedef vector<double> vd; typedef vector<vd> vvd; typedef pair<Def,pii> pip; typedef vector<pip>vip; //#define mt make_tuple //typedef tuple<pii,int,int> tp; //typedef vector<tp> vt; template<typename A,typename B>bool cmin(A &a,const B &b){return a>b?(a=b,true):false;} template<typename A,typename B>bool cmax(A &a,const B &b){return a<b?(a=b,true):false;} //template<class C>constexpr int size(const C &c){return (int)c.size();} //template<class T,size_t N> constexpr int size(const T (&xs)[N])noexcept{return (int)N;} const double PI=acos(-1); const double EPS=1e-7; Def inf = sizeof(Def) == sizeof(long long) ? 2e18 : 1e9; int dx[]={0,1,0,-1}; int dy[]={1,0,-1,0}; #define MAX 26 #define OFFSET 'A' struct Node{ int nxt[MAX+1]; // 次のalphaのノード番号 int exist; // 子ども以下に存在する文字列の数の合計 vi accept; // その文字列id Node() : exist(0){memset(nxt, -1, sizeof(nxt));} }; struct Trie{ vector<Node>nodes; int root; Trie() : root(0){nodes.push_back(Node());} void update_direct(int node,int id){ nodes[node].accept.push_back(id); } void update_child(int node,int child,int id){ ++nodes[node].exist; } void add(const string &str,int str_index,int node_index,int id){ if(str_index == str.size()) update_direct(node_index, id); else{ const int c = str[str_index] - OFFSET; if(nodes[node_index].nxt[c] == -1) { nodes[node_index].nxt[c] = (int) nodes.size(); nodes.push_back(Node()); } add(str, str_index + 1, nodes[node_index].nxt[c], id); update_child(node_index, nodes[node_index].nxt[c], id); } } void add(const string &str,int id){add(str, 0, 0, id);} void add(const string &str){add(str, nodes[0].exist);} int size(){return (nodes[0].exist);} int nodesize(){return ((int) nodes.size());} }; struct Aho_Corasick : Trie{ static const int FAIL = MAX; vi correct; Aho_Corasick() : Trie() {} void build(){ correct.resize(nodes.size()); rep(i,nodes.size())correct[i]=(int)nodes[i].accept.size(); queue<int> que; rep(i,MAX+1){ if(~nodes[0].nxt[i]) { nodes[nodes[0].nxt[i]].nxt[FAIL] = 0; que.emplace(nodes[0].nxt[i]); }else nodes[0].nxt[i] = 0; } while(!que.empty()) { Node &now = nodes[que.front()]; correct[que.front()] += correct[now.nxt[FAIL]]; que.pop(); rep(i,MAX){ if(now.nxt[i] == -1) continue; int fail = now.nxt[FAIL]; while(nodes[fail].nxt[i] == -1) { fail = nodes[fail].nxt[FAIL]; } nodes[now.nxt[i]].nxt[FAIL] = nodes[fail].nxt[i]; auto &u = nodes[now.nxt[i]].accept; auto &v = nodes[nodes[fail].nxt[i]].accept; vi accept; set_union(all(u),all(v),back_inserter(accept)); u=accept; que.emplace(now.nxt[i]); } } } int match(const string &str,vi &result,int now=0){ result.assign(size(),0); int count=0; for(auto &c:str) { while(nodes[now].nxt[c-OFFSET]==-1)now=nodes[now].nxt[FAIL]; now = nodes[now].nxt[c-OFFSET]; count += correct[now]; for(auto &v:nodes[now].accept)result[v]++; } return count; } int next(int now,char c){ while(nodes[now].nxt[c-OFFSET]==-1)now=nodes[now].nxt[FAIL]; return nodes[now].nxt[c-OFFSET]; } }; int main(){ string s; int n; cin>>s>>n; vs p(n); rep(i,n)cin>>p[i]; Aho_Corasick ac; rep(i,n)ac.add(p[i]); ac.build(); vi out(n); cout<<ac.match(s,out)<<endl; }