Guest User

LiveArchive #2164

a guest
Apr 23rd, 2012
248
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.73 KB | None | 0 0
  1. #include <algorithm>
  2. #include <cstring>
  3. #include <vector>
  4. #include <cstdio>
  5. #include <queue>
  6. using namespace std;
  7. #define nullptr 0
  8.  
  9. struct link{
  10.   int key;
  11.   link* to;
  12.   link(int key=0,link* pre=nullptr): key(key), to(pre){}
  13. };
  14. link link_pre[2400]; int link_prec;
  15.  
  16. struct aho{
  17.   aho* to[26];
  18.   aho* fail;
  19.   link* match;
  20.   static aho prep[2400];
  21.   static int prec;
  22.  
  23.   aho(){for (int i=26; i--;) to[i]=nullptr; match=nullptr;}
  24.  
  25.   void insert(char const* str,int id){
  26.     if (not *str) match=new(link_pre+link_prec++) link(id,match);
  27.     else (to[*str-'a']=(to[*str-'a']?to[*str-'a']:new(prep+prec++) aho))->insert(str+1,id);
  28.   }
  29.  
  30.   void build(){
  31.     fail=this;
  32.     queue<pair<aho*,unsigned char> > bfs;
  33.     for (bfs.push(make_pair(this,0)); not bfs.empty(); bfs.pop()){
  34.       aho* on=bfs.front().first; unsigned char c=bfs.front().second;
  35.       while (on->fail!=this and not on->fail->to[c]) on->fail=on->fail->fail;
  36.       if (on!=this and on->fail->to[c] and on->fail->to[c]!=on) on->fail=on->fail->to[c];
  37.       link* m=on->match; while (m and m->to) m=m->to;
  38.       (m?m->to:on->match)=on->fail->match;
  39.       for (int i=26; i--;) if (on->to[i]) bfs.push(make_pair(on->to[i],i)), on->to[i]->fail=on->fail;
  40.     }
  41.   }
  42. };
  43. aho aho::prep[2400];
  44. int aho::prec;
  45.  
  46. char buf[5002];
  47. int sum[5002];
  48. int got[5002][24];
  49. int goc[6000];
  50. int len[24];
  51.  
  52. bool did[5002][4096];
  53. bool dfs(int i,short need,short mask){
  54.   if (not need) return true;
  55.   if (did[i][mask]) return false; else did[i][mask]=true;
  56.   for (int j=goc[i]; j--;)
  57.     if (not (mask&(1<<got[i][j]))){
  58.       if (dfs(i-len[got[i][j]],need-1,mask|(1<<got[i][j]))) return true;
  59.     }
  60.   return false;
  61. }
  62.  
  63. int const cash[26]={
  64.    2, 3, 5, 7,11,
  65.   13,17,19,23,29,
  66.   31,37,41,43,47,
  67.   53,59,61,67,71,
  68.   73,79,83,89,97,
  69.   101
  70. };
  71.  
  72. int main(){
  73.   #ifdef twentyone
  74.   freopen("searchcat.in","r",stdin);
  75.   #endif
  76.  
  77.   for (;;){
  78.     sum[0]=0;
  79.     link_prec=0;
  80.     aho::prec=0;
  81.     aho corasick;
  82.     int tot=0,want=0;
  83.     memset(did,0,sizeof did);
  84.     int n,m; scanf("%d %d",&n,&m); if (n+m==0) break;
  85.     for (int i=0;     i<n; i++){scanf(" %s",buf); corasick.insert(buf,i); tot+=(len[i]=strlen(buf)); for (int j=0; buf[j]; j++) want+=cash[buf[j]-'a'];}
  86.     for (int i=0,j=0; i<m; i++) scanf(" %s",buf+j), j+=strlen(buf+j);
  87.     corasick.build();
  88.     aho* on=&corasick;
  89.     int res=0;
  90.     for (int i=0; buf[i]; i++){
  91.       goc[i]=0, sum[i+1]=sum[i]+cash[buf[i]-'a'];
  92.       while (on!=&corasick and not on->to[buf[i]-'a']) on=on->fail; if (on->to[buf[i]-'a']) on=on->to[buf[i]-'a'];
  93.       for (link* with=on->match; with; with=with->to) got[i][goc[i]++]=with->key;
  94.       if (i+1>=tot and sum[i+1]-sum[i-tot+1]==want) res+=dfs(i,n,0);
  95.     }
  96.     printf("%d\n",res);
  97.   }
  98. }
Add Comment
Please, Sign In to add comment