BZOJ4032: [HEOI2015]最短不公共子串
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=4032
SAM+序列自动机。。(其实我只是来贴模版的TAT
构造出两个字符串的SAM和序列自动机然后宽搜一遍就可以了(这是个拓扑图。。
#include<cstring> #include<iostream> #include<algorithm> #include<cstdio> #include<queue> #define rep(i,l,r) for (int i=l;i<=r;i++) #define down(i,l,r) for (int i=l;i>=r;i--) #define clr(x,y) memset(x,y,sizeof(x)) #define maxn 4005 #define ll long long #define inf int(1e9) using namespace std; char sa[maxn],sb[maxn]; int f[maxn][maxn]; int n,m; int read(){ int x=0,f=1; char ch=getchar(); while (!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();} while (isdigit(ch)) {x=x*10+ch-'0'; ch=getchar();} return x*f; } struct data{ struct sam{int l,fa,ch[30];} sam[maxn]; int tot,root,last,head[30]; void init(){ clr(sam,0); tot=1; clr(head,0); } void extend(int c){ int p,np,q,nq; p=last,np=++tot; last=np; sam[np].l=sam[p].l+1; for (;p&&!sam[p].ch[c];p=sam[p].fa) sam[p].ch[c]=np; if (!p) sam[np].fa=1; else { q=sam[p].ch[c]; if (sam[p].l+1==sam[q].l) sam[np].fa=q; else { nq=++tot; sam[nq].l=sam[p].l+1; memcpy(sam[nq].ch,sam[q].ch,sizeof(sam[q].ch)); sam[nq].fa=sam[q].fa; sam[np].fa=sam[q].fa=nq; for (;sam[p].ch[c]==q;p=sam[p].fa) sam[p].ch[c]=nq; } } } void sambuild(int n,char s[]){ init(); tot=last=1; rep(i,1,n) extend(s[i]-'a'); } void quebuild(int n,char s[]){ int o,p,c; init(); rep(i,0,25) head[i]=1; rep(i,1,n){ o=++tot; c=s[i]-'a'; rep(j,0,25) for (p=head[j];p&&!sam[p].ch[c];p=sam[p].fa) sam[p].ch[c]=o; sam[o].fa=head[c]; head[c]=o; } } } A,B; struct node{int x,y;}; int solve(){ queue<node> q; clr(f,0); q.push((node){1,1}); f[1][1]=0; while (!q.empty()){ int ux=q.front().x,uy=q.front().y; q.pop(); rep(i,0,25){ if (!A.sam[ux].ch[i]) continue; if (!B.sam[uy].ch[i]) return f[ux][uy]+1; int vx=A.sam[ux].ch[i],vy=B.sam[uy].ch[i]; if (!f[vx][vy]) q.push((node){vx,vy}),f[vx][vy]=f[ux][uy]+1; } } return -1; } int main(){ scanf("%s",sa+1); scanf("%s",sb+1); n=strlen(sa+1); m=strlen(sb+1); A.sambuild(n,sa); B.sambuild(m,sb); printf("%d\n",solve()); B.quebuild(m,sb); printf("%d\n",solve()); A.quebuild(n,sa); B.sambuild(m,sb); printf("%d\n",solve()); B.quebuild(m,sb); printf("%d\n",solve()); return 0; }