HDU3695(AC自动机模板题)
Posted gggyt
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU3695(AC自动机模板题)相关的知识,希望对你有一定的参考价值。
题意:给你n个字符串,再给你一个大的字符串A,问你着n个字符串在正的A和反的A里出现多少个?
其实就是AC自动机模板题啊( ╯□╰ )
正着query一次再反着query一次就好了
/* gyt Live up to every day */ #include<cstdio> #include<cmath> #include<iostream> #include<algorithm> #include<vector> #include<stack> #include<cstring>` #include<queue> #include<set> #include<string> #include<map> #include <time.h> #define PI acos(-1) using namespace std; typedef long long ll; typedef double db; const int maxn = 6000005; const ll maxm = 1e7; const ll mod = 1e9 + 7; const int INF = 0x3f3f3f; const ll inf = 1e15 + 5; const db eps = 1e-9; const int kind=26; struct node{ node *fail; node *next[kind]; int coun; void nodee() { fail=NULL; coun=0; for (int i=0; i<kind; i++) next[i]=NULL; } }*root; char str[maxn]; char tmp[maxn]; int ans=0; void updata() { node *p=root; int len=strlen(str); for (int i=0; i<len; i++) { int pos=str[i]-‘A‘; if (p->next[pos]==NULL) { p->next[pos]=new node; p->next[pos]->nodee(); p=p->next[pos]; } else p=p->next[pos]; } p->coun++; } void getfail() { node *p=root, *son, *tmp; queue<struct node*>que; que.push(p); while(!que.empty()) { tmp=que.front(); que.pop(); for (int i=0; i<26; i++) { son=tmp->next[i]; if (son!=NULL) { if (tmp==root) { son->fail=root; } else { p=tmp->fail; while(p) { if (p->next[i]) { son->fail=p->next[i]; break; } p=p->fail; } if (!p) son->fail=root; } que.push(son); } } } } void query() { int len=strlen(str); node *p, *tmp; p=root; int cnt=0; for (int i=0; i<len; i++) { int pos=str[i]-‘A‘; while(!p->next[pos]&& p!=root) p=p->fail; p=p->next[pos]; if (!p) p=root; tmp=p; while(tmp!=root) { if (tmp->coun>=0) { cnt+=tmp->coun; tmp->coun=-1; } else break; tmp=tmp->fail; } } ans+=cnt; } void solve() { ans=0; root=new node; root->nodee(); root->fail=NULL; int n; scanf("%d", &n); getchar(); for (int i=0; i<n; i++) { gets(str); updata(); } getfail(); gets(str); int len=strlen(str); int nn=0; char c; int now=0; int cnt=0; while(1) { if (now>=len) break; if (str[now]==‘[‘) { now++; while(str[now]>=‘0‘&&str[now]<=‘9‘) { nn = nn*10+(str[now]-‘0‘); now++; } c=str[now]; for (int i=0; i<nn; i++) tmp[cnt++]=c; nn=0; now++; now++; } else { // if (str[now]==‘]‘) { // now++; continue; // } tmp[cnt++]=str[now]; now++; } // cout<<str[now]<<endl; } tmp[cnt]=‘\0‘; for (int i=0; i<=cnt; i++) str[i]=tmp[i]; // cout<<str<<endl; query(); reverse(str, str+strlen(str)); // cout<<str<<endl; query(); cout<<ans<<endl; } int main() { int t = 1; // freopen("in.txt", "r", stdin); scanf("%d", &t); while(t--) solve(); return 0; }
以上是关于HDU3695(AC自动机模板题)的主要内容,如果未能解决你的问题,请参考以下文章
HDU-2222-Keywords Search(AC自动机模板)