好久没碰字典树之类的题了,搞起来有点生疏
/*
把所有母串的后缀加入字典树中
然后再扫一次所有母串的后缀,把后缀放到字典树中查询,找到第一个访问次数为1的结点返回即可
num在计数时,同一个母串的子串只能增加一次,所以用一个时间戳time数组来标记一下
*/
#include<bits/stdc++.h>
using namespace std;
#define maxn 100000
char strs[maxn][];
int n,t;
struct Trie{
int nxt[maxn*][],num[maxn*],time[maxn*];
int root,L;
int newnode(){
for(int i=;i<;i++)nxt[L][i]=-;
num[L]=,time[L]=;
return L++;
}
void init(){
L=;root=newnode();
}
void insert(char buf[]){
int len=strlen(buf);
int now=root;
for(int i=;i<len;i++){
if(nxt[now][buf[i]-'']==-)
nxt[now][buf[i]-'']=newnode();
now=nxt[now][buf[i]-''];
if(time[now]!=t)
num[now]++,time[now]=t;
}
}
int query(char buf[]){
int len=strlen(buf);
int now=root;
for(int i=;i<len;i++){
now=nxt[now][buf[i]-''];
if(num[now]==)return i;
}
return -;
}
}tr;
int main(){
int i;
cin>>n;
tr.init();
for(i=;i<=n;i++){
t=i;
cin>>strs[i];
for(int j=;j<;j++){
char tmp[]={};
strcpy(tmp,strs[i]+j);
tr.insert(tmp);
}
} for(i=;i<=n;i++){
int l=,r=,Min=;
for(int j=;j<;j++){
char buf[]={};
strcpy(buf,strs[i]+j);
int tmp=tr.query(buf);
if(tmp==-)continue;
else {
if(Min>tmp){
Min=tmp;
l=j,r=j+tmp;
}
}
}
for(int k=l;k<=r;k++)
printf("%c",strs[i][k]);
puts(""); }
}