我们已经介绍过ac自动机是什么(http://blog.csdn.net/invariance/article/details/78186894);
题面:
代码:
#include <iostream>
#include <cstdio>
#include <queue>
#include <string.h>
#include <algorithm>
using namespace std;
struct tire{
int next[100010][26],fail[100010],end[100010],mark[100010];
int root,l;
int newnode(){
for(int i=0;i<26;i++)next[l][i]=-1;
mark[l]=0;
end[l++]=0;
return l-1;
}
void init(){
l=0;
root=newnode();
}
void insert(char b[]){
int len=strlen(b);
int now=root;
for(int i=0;i<len;i++){
if(next[now][b[i]-'a']==-1)next[now][b[i]-'a']=newnode();
now=next[now][b[i]-'a'];
}
end[now]++;
}
void build(){
queue<int>p;
fail[root]=root;
for(int i=0;i<26;i++)if(next[root][i]==-1)next[root][i]=root;
else {
fail[next[root][i]]=root;
p.push(next[root][i]);
}
while(!p.empty()){
int now=p.front();
p.pop();
for(int i=0;i<26;i++){
if(next[now][i]==-1)next[now][i]=next[fail[now]][i];
else{
fail[next[now][i]]=next[fail[now]][i];
p.push(next[now][i]);
}
}
}
}
int query(char b[]){
int len=strlen(b);
int now=root;
int ans=0;
for(int i=0;i<len;i++){
now=next[now][b[i]-'a'];
int tmp=now;
while(tmp!=root&&mark[tmp]==0){
ans+=end[tmp];
mark[tmp]=1;
end[tmp]=0;
tmp=fail[tmp];
}
}
return ans;
}
};
char buf[100010];
char as[100010];
tire ac;
int main(){
int t;
cin>>t;
while (t--) {
int n;
cin>>n;
ac.init();
int len=0;
for(int i=0;i<n;i++){
scanf("%s",buf);
int l=strlen(buf);
if(len<l){
len=l;
strcpy(as, buf);
}
ac.insert(buf);
}
ac.build();
if (ac.query(as)==n) {
for (int i=0; i<len; i++) {
printf("%c",as[i]);
}
printf("\n");
}
else cout<<"No"<<endl;
}
}