题目描述:
给出 nn 个字符串 ,求S1S1中最短的子串满足其不是S2,...,SnS2,...,Sn的子串。字符串总长不超过250000。
解题思路:
将所有串建立广义SAM,维护每个点id的最大值即可判断其是否唯一是 S1S1 的子串,然后贪心找合法串即可。
#include<bits/stdc++.h>
#define ll long long
#define pb push_back
using namespace std;
ll getint()
{
ll i=0,f=1;char c;
for(c=getchar();(c!='-')&&(c<'0'||c>'9');c=getchar());
if(c=='-')c=getchar(),f=-1;
for(;c>='0'&&c<='9';c=getchar())i=(i<<3)+(i<<1)+c-'0';
return i*f;
}
const int N=500005;
int n,tot,last,fa[N],son[N][26],id[N],mx[N],len[N],c[N],q[N];
char s[N];
void clear()
{
for(int i=1;i<=tot;i++)
{
memset(son[i],0,sizeof(son[i]));
mx[i]=fa[i]=id[i]=len[i]=0;
}tot=1;
}
void extend(int c)
{
int p=last;
if(son[p][c])
{
int q=son[p][c];
if(mx[q]==mx[p]+1)last=q;
else
{
int nq=last=++tot;mx[nq]=mx[p]+1;
memcpy(son[nq],son[q],sizeof(son[q])),fa[nq]=fa[q],fa[q]=nq;
while(p&&son[p][c]==q)son[p][c]=nq,p=fa[p];
}
}
else
{
int np=last=++tot;mx[np]=mx[p]+1;
while(p&&!son[p][c])son[p][c]=np,p=fa[p];
if(!p)fa[np]=1;
else
{
int q=son[p][c];
if(mx[q]==mx[p]+1)fa[np]=q;
else
{
int nq=++tot;mx[nq]=mx[p]+1;
memcpy(son[nq],son[q],sizeof(son[q])),fa[nq]=fa[q],fa[q]=fa[np]=nq;
while(p&&son[p][c]==q)son[p][c]=nq,p=fa[p];
}
}
}
}
void W(int p)
{
if(len[p]==1)return;
int j=26,ml=1e9;
for(int i=0;i<26;i++)
if(id[son[p][i]]==1&&ml>len[son[p][i]])
j=i,ml=len[son[p][i]];
if(p==1&&j==26)printf("Impossible");
if(j!=26)putchar('a'+j),W(son[p][j]);
}
void solve(int t)
{
clear();n=getint();
for(int i=1;i<=n;i++)
{
scanf("%s",s);last=1;
for(int j=0,l=strlen(s);j<l;j++)extend(s[j]-'a'),id[last]=i;
}
for(int i=0;i<=tot;i++)c[i]=0;
for(int i=1;i<=tot;i++)c[mx[i]]++;
for(int i=1;i<=tot;i++)c[i]+=c[i-1];
for(int i=tot;i;i--)q[c[mx[i]]--]=i;
for(int i=tot,u;i;i--)
{
u=q[i],id[u],len[u]=(id[u]==1);
if(fa[u])id[fa[u]]=max(id[fa[u]],id[u]);
}
for(int i=tot;i;i--)
{
int u=q[i];
for(int j=0;j<26;j++)if(id[son[u][j]]==1)
{
int v=son[u][j];
if(id[u]!=1)id[u]=1,len[u]=len[v]+1;
else len[u]=min(len[u],len[v]+1);
}
}
printf("Case #%d: ",t);
W(1),putchar('\n');
}
int main()
{
//freopen("lx.in","r",stdin);
for(int T=getint(),t=1;T;T--,t++)solve(t);
return 0;
}