题意:给你n个母串,m个匹配串,让你求出对于每个母串 所有匹配串出现的次数和。
思路:ac自动机模板题,加入一个数组val[i] 表示以i节点结束时匹配了几个匹配串
代码:
#include <algorithm> #include <iostream> #include <sstream> #include <cstdlib> #include <cstring> #include <iomanip> #include <cstdio> #include <string> #include <bitset> #include <vector> #include <queue> #include <stack> #include <cmath> #include <list> #include <map> #include <set> #define sss(a,b,c) scanf("%d%d%d",&a,&b,&c) #define mem1(a) memset(a,-1,sizeof(a)) #define mem(a) memset(a,0,sizeof(a)) #define ss(a,b) scanf("%d%d",&a,&b) #define s(a) scanf("%d",&a) #define p(a) printf("%d\n", a) #define INF 0x3f3f3f3f #define w(a) while(a) #define PI acos(-1.0) #define LL long long #define eps 10E-9 #define N 200000+20 #define mod 1000000007 const int SIGMA_SIZE=26; const int MAXN=100010; const int MAXNODE=600010; using namespace std; void mys(int& res) { int flag=0; char ch; while(!(((ch=getchar())>='0'&&ch<='9')||ch=='-')) if(ch==EOF) res=INF; if(ch=='-') flag=1; else if(ch>='0'&&ch<='9') res=ch-'0'; while((ch=getchar())>='0'&&ch<='9') res=res*10+ch-'0'; res=flag?-res:res; } void myp(int a) { if(a>9) myp(a/10); putchar(a%10+'0'); } /*************************THE END OF TEMPLATE************************/ int n,m; LL ans; string str1[MAXN],str2[MAXN]; struct AC{ int ch[MAXNODE][SIGMA_SIZE],f[MAXNODE],sz; LL val[MAXNODE]; void init(){ memset(ch[0],0,sizeof(ch[0])); val[0]=0; sz=1; } int idx(char c){ return c-'a'; } void insert(string s){ int u=0,len=s.size(); for(int i=0;i<len;i++){ int c=idx(s[i]); if(!ch[u][c]){ memset(ch[sz],0,sizeof(ch[sz])); val[sz]=0; ch[u][c]=sz++; } u=ch[u][c]; } val[u]++; } void get_fail(){ queue<int> q; f[0]=0; for(int c=0;c<SIGMA_SIZE;c++){ int u=ch[0][c]; if(u){ f[u]=0; q.push(u); } } while(!q.empty()){ int r=q.front(); q.pop(); for(int c=0;c<SIGMA_SIZE;c++){ int u=ch[r][c]; if(!u){ ch[r][c]=ch[f[r]][c]; continue; } q.push(u); f[u]=ch[f[r]][c]; val[u]+=val[f[u]]; } } } void find(string T){ int j=0; int len=T.size(); for(int i=0;i<len;i++){ int c=idx(T[i]); j=ch[j][c]; ans+=val[j]; } } }ac; int main(){ int t; s(t); while(t--){ ss(n, m); for(int i=1;i<=n;i++) cin>>str1[i]; ac.init(); for(int i=1;i<=m;i++){ cin>>str2[i]; ac.insert(str2[i]); } ac.get_fail(); for(int i=1;i<=n;i++){ ans=0; ac.find(str1[i]); printf("%I64d\n",ans); } } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-23 20:12:19