hdu2896

AC自动机的裸题。虽然是水题却做了很久,居然在每次查询的脑残的去修改字典树的信息。

还有数组开小了居然会返回wa。。。

  1 #include<iostream>
  2 #include<stdio.h>
  3 #include<string.h>
  4 #include<queue>
  5 #include<algorithm>
  6 using namespace std;
  7 const int maxn=85010;
  8 const int sig=100;
  9 int ch[maxn][sig],last[maxn],f[maxn],num,cnt,top,n,m,val[maxn],vis[10000];
 10 char p[maxn];
 11 
 12 void init()
 13 {
 14     top=1;
 15     num=0;
 16     memset(ch[0],0,sizeof(ch));
 17     memset(f,0,sizeof(f));
 18 }
 19 
 20 int idx(char c)
 21 {
 22     return c-' ';
 23 }
 24 void insert(char *s,int v)
 25 {
 26     int u=0,n=strlen(s);
 27     for(int i=0;i<n;i++)
 28     {
 29         int c=idx(s[i]);
 30         if(!ch[u][c])
 31         {
 32             memset(ch[top],0,sizeof(ch[top]));
 33             val[top]=0;
 34             ch[u][c]=top++;
 35         }
 36         u=ch[u][c];
 37     }
 38     val[u]=v;
 39 }
 40 
 41 void getfail()
 42 {
 43     queue<int> q;
 44     f[0]=0;
 45     int c,u;
 46     for(c=0;c<sig;c++)
 47     {
 48         u=ch[0][c];
 49         if(u){f[u]=0;q.push(u);last[u]=0;}
 50     }
 51     int r,v;
 52     while(!q.empty())
 53     {
 54         r=q.front();q.pop();
 55         for(c=0;c<sig;c++)
 56         {
 57             u=ch[r][c];
 58             if(!u) {ch[r][c]=ch[f[r]][c];continue;}
 59             q.push(u);
 60             v=f[r];
 61             f[u]=ch[v][c];
 62             last[u]=val[last[u]]?f[u]:last[f[u]];
 63         }
 64     }
 65 }
 66 
 67 void print(int j)
 68 {
 69     if(j)
 70     {
 71         if(cnt==0)
 72         {
 73             vis[val[j]]=1;
 74             cnt++;
 75             num++;
 76         }
 77         else
 78         vis[val[j]]=1;
 79         print(last[j]);
 80     }
 81 }
 82 void find(char *s,int v)
 83 {
 84     int n=strlen(s),i;
 85     int j=0,c;
 86     cnt=0;
 87     memset(vis,0,sizeof(vis));
 88     for(i=0;i<n;i++)
 89     {
 90         c=idx(s[i]);
 91         while(j&&!ch[j][c]) j=f[j];
 92         j=ch[j][c];
 93         if(val[j]) print(j);
 94         else if(last[j]) print(last[j]);
 95     }
 96 
 97     if(cnt)
 98     {
 99          printf("web %d:",v);
100          for(i=1;i<=n;i++)
101          {
102             if(vis[i])
103             printf(" %d",i);
104          }
105          printf("\n");
106     }
107 }
108 int main()
109 {
110     //freopen("test.txt","r",stdin);
111     scanf("%d",&n);
112         int i,j;
113         for(i=0;i<n;i++)
114         {
115             scanf("%s",p);
116             insert(p,i+1);
117         }
118         getfail();
119         scanf("%d",&m);
120         for(i=0;i<m;i++)
121         {
122             scanf("%s",p);
123             find(p,i+1);
124         }
125         printf("total: %d\n",num);
126     return 0;
127 }
View Code

 

posted @ 2013-05-26 00:18  longlongago  Views(126)  Comments(0Edit  收藏  举报