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 }