poj 4042

来源:互联网 发布:英雄联盟 mac版 编辑:程序博客网 时间:2024/06/01 18:21

题目意思是用主串去匹配模式串,如果a和b都在主串中出现了且a是b的子串,这只算b,求出能够匹配的模式串。

我的超时代码,不知道为什么就能超时。。。

#include <cstdlib>#include <iostream>#include <cstring>#include <cstdio>using namespace std;const int CH=26;const int NODE=6100000;int chd[NODE][CH],fail[NODE],word[NODE],sz;char s1[6100010],s2[6100010];bool vis[3100];void Ins(char *s,int val){     int p=0;     for(;*s;s++)     {          int id=(*s)-'A';                   if(!chd[p][id])                        {                memset(chd[sz],0,sizeof(chd[sz]));                                             word[sz]=0;                chd[p][id]=sz++;          }          p=chd[p][id];     }     word[p]=val;}int Que[NODE];void AC(){     int *s=Que,*e=Que;     for(int i=0;i<CH;i++)       if(chd[0][i]){           *e++=chd[0][i];                         fail[chd[0][i]]=0;       }     while(s!=e)     {         int p=*s++;                    for(int i=0;i<CH;i++)           if(chd[p][i])           {               int k=chd[p][i];                         fail[k]=chd[fail[p]][i];               *e++=chd[p][i];           }           else             chd[p][i]=chd[fail[p]][i];     }  }void change(char *s){     int num=0;     for(;*s;s++)            if((*s)=='[')       {             s++;                     int cnt=(*s++)-'0';             while((*s)>='0'&&(*s)<='9') cnt=cnt*10+(*s)-'0',s++;                                       for(int i=0;i<cnt;i++) s2[num++]=(*s);             s++;       }       else  s2[num++]=(*s);       s2[num]='\0';}void solve(){     int p=0;     for(int i=0;s2[i];i++)         {             p=chd[p][s2[i]-'A'];                  for(int tmp=fail[p];tmp>0&&word[tmp]>=0;tmp=fail[tmp])              if(word[tmp]>0)               {                 vis[word[tmp]]=1,word[tmp]=-1;                   break;              }     }}char ss[2510][1200];void Ins1(char *s,int val){     int p=0;     for(;*s;s++)     {          int id=(*s)-'A';                   if(!chd[p][id])                        {                memset(chd[sz],0,sizeof(chd[sz]));                                             word[sz]=0;                chd[p][id]=sz++;          }          p=chd[p][id];          if(word[p]>0) vis[word[p]]=0;     }     word[p]=val;}void AC1(){     int *s=Que,*e=Que;     for(int i=0;i<CH;i++)       if(chd[0][i])       {           *e++=chd[0][i];                         fail[chd[0][i]]=0;       }     while(s!=e)     {         int p=*s++;                    for(int i=0;i<CH;i++)           if(chd[p][i])           {               int k=chd[p][i];                         fail[k]=chd[fail[p]][i];               for(int tmp=fail[k];tmp>0;tmp=fail[tmp])                 if(word[tmp]>=0) vis[word[tmp]]=0,word[tmp]=-1;                 else break;               *e++=chd[p][i];           }           else             chd[p][i]=chd[fail[p]][i];     }  }int main(){      int ca,n;      scanf("%d",&ca);      while(ca--)      {           scanf("%d",&n);           getchar();           sz=1;           memset(chd[0],0,sizeof(chd[0]));              for(int i=0;i<n;i++)           {               scanf("%s",ss[i]);                       change(ss[i]);               Ins(s2,i+1);           }           AC();           memset(vis,0,sizeof(vis));           scanf("%s",s1);            change(s1);           solve();           sz=1;           memset(chd[0],0,sizeof(chd[0]));           for(int i=0;i<n;i++)               if(vis[i+1]) Ins1(ss[i],i+1);                   AC1();           int ans=0;           for(int i=1;i<=n;i++) if(vis[i]) ans++;           printf("%d\n",ans);      }      return 0;    }/*43[2F]RRRRR[4F]RRE*/


原创粉丝点击