HDU 5880 Family View

  1 /*
  2 HDU 5880 Family View
  3 http://acm.hdu.edu.cn/showproblem.php?pid=5880
  4 AC自动机
  5 注意不要直接全把节点初始化,将其当做内存池来用,
  6 用的时候再初始化,否则会MLE
  7 */
  8 #include<cstdio>
  9 #include<cstring>
 10 #include<queue>
 11 #include<algorithm>
 12 using namespace std;
 13 const int Nmax=1000010;
 14 const int Totmax=1000010;
 15 struct Aho
 16 {
 17     struct State
 18     {
 19         int next[26];
 20         int cnt,fail,num;
 21     }state_table[Totmax];
 22 
 23     int size;
 24     int ans[Nmax];
 25     queue<int> Q;
 26     void init()
 27     {
 28         for(int i=0;i<Nmax;i++)
 29             ans[i]=0;
 30         while(Q.size())
 31             Q.pop();
 32         for(int j=0;j<26;j++)                
 33             state_table[0].next[j]=-1;
 34         state_table[0].fail=state_table[0].cnt=state_table[0].num=0;
 35         size=1;
 36     }
 37 
 38     void insert(char *s)
 39     {
 40         int n=strlen(s);
 41         int now=0;
 42         for(int i=0;i<n;i++)
 43         {
 44             char c=s[i];
 45             if(state_table[now].next[c-'a']==-1)
 46             {
 47                 for(int j=0;j<26;j++)
 48                     state_table[size].next[j]=-1;
 49                 state_table[size].cnt=state_table[size].fail=state_table[size].num=0;
 50                 state_table[now].next[c-'a']=size++;
 51             }
 52             now=state_table[now].next[c-'a'];
 53         }
 54         state_table[now].cnt++;
 55         state_table[now].num=n;
 56     }
 57 
 58     void build()
 59     {
 60         Q.push(0);
 61         state_table[0].fail=0;
 62         while(Q.size())
 63         {
 64             int now=Q.front();
 65             Q.pop();
 66             for(int i=0;i<26;i++)
 67             {
 68                 if(now==0)
 69                 {
 70                     if(state_table[now].next[i]==-1)
 71                         state_table[now].next[i]=0;
 72                     else
 73                     {
 74                         state_table[ state_table[now].next[i] ].fail=0;
 75                         Q.push(state_table[now].next[i]);
 76                     }
 77                 }
 78                 else
 79                 {
 80                     if(state_table[now].next[i]==-1)
 81                     {
 82                         state_table[now].next[i]=state_table[ state_table[now].fail ].next[i]; 
 83                     }    
 84                     else
 85                     {
 86                         state_table[ state_table[now].next[i] ].fail=state_table[ state_table[now].fail ].next[i];
 87                         Q.push(state_table[now].next[i]);
 88                     }
 89                 }
 90                 
 91             }
 92         }
 93     }
 94 
 95     void match(char *s)
 96     {
 97         int n=strlen(s);
 98         int now=0;
 99         for(int i=0;i<n;i++)
100         {
101             char c=s[i];
102             if(c>='A' && c<='Z')
103                 now=state_table[now].next[c-'A'];
104             else if(c>='a' && c<='z')
105                 now=state_table[now].next[c-'a'];
106             else
107                 now=0;
108             int x = now;
109             while(x != 0)
110             {
111                 if(state_table[x].cnt)
112                 {
113                     int k=state_table[x].num;
114                     int j=i;
115                     while(k--)
116                     {
117                         s[j]='*';
118                         j--;
119                     }
120                     break;
121                 }
122                 x = state_table[x].fail;
123             }
124  
125         }
126     }
127 
128      void solve(char *s)
129      {
130         int now = 0;
131         int len = strlen(s);
132         int index;
133         for(int i = 0; i < len ; ++i)
134         {
135             if(s[i] >= 'A' && s[i] <= 'Z')
136                 index = s[i] - 'A';
137             else if(s[i] >= 'a' && s[i] <= 'z')
138                 index = s[i] - 'a';
139             else 
140             {
141                 now=0;
142                 continue;
143             }
144             now =state_table[now].next[index];
145             int x = now;
146             while(x != 0)
147             {
148                 if(state_table[x].cnt)
149                 {
150                     ans[i + 1] -= 1;
151                     ans[i - state_table[x].num + 1] += 1;
152                     break;
153                 }
154                 x = state_table[x].fail;
155             }
156         }
157     }
158 
159     void print(char *s)
160     {
161         long long res = 0;
162         int len = strlen(s);
163         for(int i = 0; i < len; ++i)
164         {
165             res += ans[i];
166             if(res <= 0)
167                 printf("%c", s[i]);
168             else printf("*");
169         }
170         puts("");
171     }
172 
173 
174 
175 
176 
177 }aho;
178 char s[Nmax];
179 int main()
180 {
181     int t;
182     //freopen("in.in","r",stdin);
183     scanf("%d",&t);
184     while(t--)
185     {
186         int n;
187         aho.init();
188         scanf("%d",&n);
189         while(n--)
190         {
191             scanf("%s",s);
192             aho.insert(s);
193         }
194         getchar();
195         gets(s);
196         //printf("%s\n",s);
197         aho.build();
198         //aho.match(s);
199         //printf("%s\n",s); 
200         
201         aho.solve(s);
202         aho.print(s);
203         
204 
205     }
206     return 0;
207 }

 

posted @ 2017-03-12 10:54  BBBob  阅读(249)  评论(0编辑  收藏  举报