String HDU - 6096 多校#6 自动机
想总结的太多了。。。白天再来吧
#include<bits/stdc++.h> #include<stdio.h> #include<algorithm> #include<queue> #include<string.h> #include<iostream> #include<math.h> #include<set> #include<map> #include<vector> #include<iomanip> using namespace std; #define ll long long #define ull unsigned long long #define pb push_back #define FOR(a) for(int i=1;i<=a;i++) const int inf=0x3f3f3f3f; const int maxn=2e6+71; const long long mod=998244353; const int sigma=27; int cnt[maxn]; struct automata{ int ch[maxn][sigma]; int val[maxn]; //是第几个串 int f[maxn]; int len[maxn]; //字典树深度 int sz; int idx(char x){return x-'a';} int newnode(){ memset(ch[sz],0,sizeof(ch[sz])); f[sz]=val[sz]=0; return sz++; } void init(){ memset(val,0,sizeof val); sz=0; newnode(); } int insert(char *s,int v){ int u=0; int _len=strlen(s); for(int i=0;i<_len;i++){ int id=s[i]-'a';//s[i]-'a'; //cout<<id<<endl; if(!ch[u][id]){ len[sz]=i+1; ch[u][id]=newnode(); } u=ch[u][id]; } val[u]=v; //cout<<u<<" "<<v<<" "<<len[u]<<endl; return u; } void build(){ queue<int>q; q.push(0); while(!q.empty()){ int u=q.front();q.pop(); for(int i=0;i<sigma;i++){ int v=ch[u][i]; if(!v)ch[u][i]=ch[f[u]][i]; else q.push(v); if(u&&v)f[v]=ch[f[u]][i]; } } } void query(char* s){ int _len=strlen(s)/2+1; //cout<<_len<<endl; int u=0; for(int i=0;s[i];i++){ //cout<<s[i]<<endl; u=ch[u][s[i]-'a']; int j=u; //if(!val[j])continue; //非文本串结尾 while(j){ //cout<<j<<" "<<f[j]<<endl; //bug! if(len[j]<=_len)cnt[j]++; j=f[j]; } } //cout<<"!!"<<endl; } }ac; char s[maxn]; int pos[maxn];//第i个串的开头 char pre[maxn],suf[maxn]; int id[maxn]; int main(){ int T,n,q; //ac.init(); //char t1[10]="wq{qw"; //char t2[10]="q{q"; //ac.insert(t1,1); //ac.insert(t2,2); //ac.build(); //for(int i=1;i<=8;i++){ // cout<<i<<" "<<ac.f[i]<<endl; //} //return 0; scanf("%d",&T); while(T--){ memset(id,0,sizeof id); memset(pos,0,sizeof pos); memset(cnt,0,sizeof cnt); memset(ac.len,0,sizeof ac.len); ac.init(); scanf("%d%d",&n,&q); for(int i=1;i<=n;i++){ scanf("%s",s+pos[i]);int len=strlen(s+pos[i]); s[pos[i]+len]='{'; for(int j=pos[i];j<pos[i]+len;j++){ s[j+len+1]=s[j]; } s[pos[i]+len+len+1]='\0'; pos[i+1]=pos[i]+strlen(s+pos[i])+1; } for(int i=1;i<=q;i++){ scanf("%s",pre); scanf("%s",suf); int len1=strlen(suf); suf[len1]='{';int len=strlen(pre); for(int j=0;j<len;j++){ suf[len1+j+1]=pre[j]; } suf[len+len1+1]='\0'; id[i]=ac.insert(suf,i); } //char t1[10]="wq#qw"; //char t2[10]="q#q"; //ac.insert(t1,1); //ac.insert(t2,2); ac.build(); //for(int i=1;i<=8;i++){ // cout<<i<<" "<<ac.f[i]<<endl; //} //return 0; //ac.query(s+pos[1]); //printf("%d %d\n",cnt[1],cnt[2]); for(int i=1;i<=n;i++){ ac.query(s+pos[i]); } for(int i=1;i<=q;i++){ printf("%d\n",cnt[id[i]]); } } }