hdu2896 ac自动机
这题还是ac自动机裸题,只不过就是格式很烦人
有几个坑点:输入可能有空格,ascll可见字符从32开始到126有95个
wa点,用string输入,不能含空格,用scanf输入字符数组时没有memset,每次计算set里面的末尾值之后就清空了
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> #define fi first #define se second #define mp make_pair #define pb push_back #define pii pair<int,int> #define C 0.5772156649 #define pi acos(-1.0) #define ll long long #define mod 1000000007 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 using namespace std; const double g=10.0,eps=1e-7; const int N=100000+10,maxn=60000+10,inf=0x3f3f3f; struct Trie{ int fail[N],Next[N][95]; set<int>cnt[N]; int tot,root,sum; int newnode() { for(int i=0;i<95;i++) Next[tot][i]=-1; cnt[tot].clear(); return tot++; } void init() { sum=0; tot=0; root=newnode(); } void insertstring(char *s,int k) { int now=root,len=strlen(s); for(int i=0;i<len;i++) { if(Next[now][s[i]-' ']==-1) Next[now][s[i]-' ']=newnode(); now=Next[now][s[i]-' ']; } cnt[now].insert(k); } void build() { queue<int>q; fail[root]=root; for(int i=0;i<95;i++) { if(Next[root][i]==-1)Next[root][i]=root; else { fail[Next[root][i]]=root; q.push(Next[root][i]); } } while(!q.empty()) { int now=q.front(); q.pop(); for(int i=0;i<95;i++) { if(Next[now][i]==-1)Next[now][i]=Next[fail[now]][i]; else { fail[Next[now][i]]=Next[fail[now]][i]; q.push(Next[now][i]); } } } } void query(char *s,int k) { int now=root,len=strlen(s); set<int>ans; for(int i=0;i<len;i++) { now=Next[now][s[i]-' ']; int temp=now; while(temp!=root) { for(auto x : cnt[temp]) ans.insert(x); temp=fail[temp]; } } if(ans.size()==0)return ; printf("web %d:",k); for(auto x : ans) printf(" %d",x); puts(""); sum++; } }; Trie ac; char s[N]; int main() { /* ios::sync_with_stdio(false); cin.tie(0);*/ int n; scanf("%d",&n); ac.init(); getchar(); for(int i=1;i<=n;i++) { int cnt=0; char p; memset(s,0,sizeof s); while((p=getchar())!='\n') { s[cnt++]=p; } ac.insertstring(s,i); } ac.build(); int k; scanf("%d",&k); getchar(); for(int i=1;i<=k;i++) { int cnt=0; char p; memset(s,0,sizeof s); while((p=getchar())!='\n') { s[cnt++]=p; } /* cout<<strlen(s)<<endl; printf("%s\n",s);*/ ac.query(s,i); } printf("total: %d\n",ac.sum); return 0; } /******************** 3 aaa bbb ccc 2 aaabbbccc abbb cc ********************/