【洛谷P4112】【HEOI2015】—最短不公共子串(序列自动机+后缀自动机+DP)

传送门

对2个串分别建出SamSam和序列自动机

对四种情况分别跑一次n2dpn^2dp即可

#include<bits/stdc++.h>
using namespace std;
const int RLEN=1<<20|1;
inline char gc(){
    static char ibuf[RLEN],*ib,*ob;
    (ob==ib)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
    return (ob==ib)?EOF:*ib++;
}
#define gc getchar
inline int read(){
    char ch=gc();
    int res=0,f=1;
    while(!isdigit(ch))f^=ch=='-',ch=gc();
    while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
    return f?res:-res;
}
#define ll long long
#define re register
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
#define cs const
#define bg begin
#define poly vector<int>
template<class T>inline void chemx(T &a,T b){a<b?a=b:0;}
template<class T>inline void chemn(T &a,T b){a>b?a=b:0;}
cs int N=2005,M=N<<1;
struct Sam{
	int fa[M],len[M],nxt[M][26],tot,last;
	inline void init(){
		fa[0]=-1;
	}
	inline void insert(int c){
		int cur=++tot,p=last;last=cur;
		len[cur]=len[p]+1;
		for(;~p&&!nxt[p][c];p=fa[p])nxt[p][c]=cur;
		if(p==-1)fa[cur]=0;
		else {
			int q=nxt[p][c];
			if(len[p]+1==len[q])fa[cur]=q;
			else{
				int clo=++tot;
				len[clo]=len[p]+1,fa[clo]=fa[q];
				memcpy(nxt[clo],nxt[q],sizeof(nxt[q]));
				for(;~p&&nxt[p][c]==q;p=fa[p])nxt[p][c]=clo;
				fa[q]=fa[cur]=clo;
			}
		}
	}
	inline  void build(char *s){
		init();
		for(int i=1,len=strlen(s+1);i<=len;i++)
		insert(s[i]-'a');
	}
}a,b;
struct Seam{
	int nxt[M][26];
	inline void insert(char *s){
		for(int i=strlen(s+1);i>=1;i--){
			int c=s[i]-'a';
			for(int j=0;j<26;j++)if(j!=c)
			nxt[i-1][j]=nxt[i][j];
			nxt[i-1][c]=i;
		}
	}
}A,B;
int nxt1[M][26],nxt2[M][26],n,m;
int f[M][M];
int dfs(int p1,int p2){
	if(f[p1][p2])return f[p1][p2];
	int res=1e9;
	for(int i=0;i<26;i++){
		if(nxt1[p1][i]&&!nxt2[p2][i])
			return f[p1][p2]=1;
		if(nxt1[p1][i]&&nxt2[p2][i])
		chemn(res,dfs(nxt1[p1][i],nxt2[p2][i])+1);
	}
	return f[p1][p2]=res;
}
inline void calc(){
	memset(f,0,sizeof(f));
	int res=dfs(0,0);
	if(res==1e9)res=-1;
	cout<<res<<'
';
}
char s[N];
int main(){
	scanf("%s",s+1);
	n=strlen(s+1);
	a.build(s),A.insert(s);
	scanf("%s",s+1);
	m=strlen(s+1);
	b.build(s),B.insert(s);
	memcpy(nxt1,a.nxt,sizeof(a.nxt));
	memcpy(nxt2,b.nxt,sizeof(b.nxt));
	calc();
	memcpy(nxt1,a.nxt,sizeof(a.nxt));
	memcpy(nxt2,B.nxt,sizeof(B.nxt));
	calc();
	memcpy(nxt1,A.nxt,sizeof(A.nxt));
	memcpy(nxt2,b.nxt,sizeof(b.nxt));
	calc();
	memcpy(nxt1,A.nxt,sizeof(A.nxt));
	memcpy(nxt2,B.nxt,sizeof(B.nxt));
	calc();
}