【AC自动机】HDU 6096

主要是有个技巧

每个询问串s+'{'+s拼接起来

每个模板串p+'{'+s拼接起来

所有模板串建立AC自动机

询问串直接匹配,

同时还要满足询问串原长度+1>=模板串拼接后长度,否则会因前缀和后缀有重叠部分而不符合

  1 // #include <bits/stdc++.h>
  2 #include <iostream>
  3 #include <cstdio>
  4 #include <queue>
  5 #include <cstring>
  6 #include <cctype>
  7 #include <set>
  8 #include <cmath>
  9 #include <algorithm>
 10 #define For(i,a,b) for(int i=a;i<=b;++i)
 11 #define Dec(i,b,a) for(int i=b;i>=a;--i)
 12 #define file() freopen("c://users/asus/desktop/v.txt","r",stdin);
 13 #define inf 0x3f3f3f3f
 14 using namespace std;
 15 
 16 typedef long long ll;
 17 inline ll qr(){
 18     ll x=0,f=1; char ch;
 19     while(!isdigit(ch=getchar())) if(ch=='-') f=-1;
 20     while(isdigit(ch)){x=(x<<3)+(x<<1)+(ch^48); ch=getchar();}
 21     return x*f;
 22 }
 23 const int N = 100010, M = 1000010;
 24 string Q[N],s,p;
 25 int c[N<<5][27],pos[N],f[N<<5],len[N<<5],ct;
 26 int n,q,ans[N<<5],l[N];
 27 void clr(int x)
 28 {
 29     memset(c[x],0,sizeof c[x]);
 30     f[x]=len[x]=0;
 31 }
 32 void init()
 33 {
 34     fill(ans,ans+1+ct,0); 
 35     fill(pos,pos+1+q,0); 
 36     clr(ct=0);
 37 }
 38 void ins(string s,int k)
 39 {
 40     int u=0;
 41     for(int i=0;i<s.length();++i)
 42     {
 43         int v=s[i]-'a';
 44         if(!c[u][v]) c[u][v]=++ct,clr(ct),len[ct]=i+1;
 45         u=c[u][v];
 46     }
 47     pos[k]=u;
 48 }
 49 void getfail()
 50 {
 51     queue<int> q;
 52     For(i,0,26) if(c[0][i]) q.push(c[0][i]);
 53     while(!q.empty())
 54     {
 55         int u=q.front(); q.pop();
 56         For(i,0,26)
 57         {
 58             int &v=c[u][i];
 59             if(v) f[v]=c[f[u]][i],q.push(v);
 60             else v=c[f[u]][i];
 61         }
 62     }
 63 }
 64 void qry(string s,int k)
 65 {
 66     int u=0;
 67     for(int i=0;i<s.length();++i)
 68     {
 69         u=c[u][s[i]-'a'];
 70         for(int t=u; t; t=f[t])
 71             if(len[t]<=k) ans[t]++;
 72     }
 73 }
 74 int main()
 75 {
 76     // file();
 77     ios::sync_with_stdio(0);
 78     int kase; cin >> kase;
 79     while(kase--)
 80     {
 81         cin >> n >> q;
 82         init();
 83         For(i,1,n)
 84         {
 85             cin >> Q[i];
 86             l[i]=Q[i].length()+1;
 87             Q[i]=Q[i]+'{'+Q[i];
 88         }
 89         For(i,1,q)
 90         {
 91             cin >> s >> p;
 92             s = p+'{'+s;
 93             ins(s,i);
 94         }
 95         getfail();
 96         For(i,1,n) qry(Q[i],l[i]);
 97         For(i,1,q) cout<<ans[pos[i]]<<"\n";
 98     }
 99     return 0;
100 }
View Code

猜你喜欢

转载自www.cnblogs.com/uuuxxllj/p/10885249.html