ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

CF427D Match & Catch 题解

2022-05-18 21:34:20  阅读:144  来源: 互联网

标签:nxt int 题解 void len son swap Catch Match


题面

虽然 \(n,m\leq 5000\),但是这题是 \(O((n+m)|\Sigma|)\) 的。首先建 \(S\) 的 SAM,拿 \(T\) 上去跑可以得到 \(T\) 每个前缀的匹配区间(在 \(S\) 中只出现一次)。接着建 \(T\) 的 SAM,也可以求出每个前缀在 \(T\) 中只出现一次的区间。做一个区间交,取一个全局 \(\min\) 即可。

点击查看代码
inline void clearvector(std::vector<int> &a){std::vector<int> b;std::swap(a,b);}
const int N=5000+13;
char s[N],t[N];
int nxt[N<<1],len[N<<1],ptot,lastpos,cnt[N<<1];
std::vector<int> son[N<<1],zrzak;
std::vector<int> G[N<<1];
inline void clear(){
	for(int i=1;i<=ptot;++i) clearvector(son[i]),clearvector(G[i]),cnt[i]=nxt[i]=len[i]=0;
	son[1].resize(26),zrzak.resize(26);
	ptot=lastpos=1;
}
inline int newpos(std::vector<int> nson,int nlen){return len[++ptot]=nlen,std::swap(son[ptot],nson),ptot;}
inline void insert(int c){
	int p=lastpos,u=newpos(zrzak,len[p]+1);cnt[u]=1;
	while(p&&!son[p][c]) son[p][c]=u,p=nxt[p];
	lastpos=u;
	if(!p) return nxt[u]=1,void();
	int d=son[p][c];
	if(len[d]==len[p]+1) nxt[u]=d;
	else{
		int v=newpos(son[d],len[p]+1);
		nxt[v]=nxt[d],nxt[u]=nxt[d]=v;
		while(p&&son[p][c]==d) son[p][c]=v,p=nxt[p];
	}
}
void dfs(int u){for(auto v:G[u])dfs(v),cnt[u]+=cnt[v];}
pii a[N];
int main(){
	clear();
	read(s+1),read(t+1);
	int n=strlen(s+1),m=strlen(t+1);
	for(int i=1;i<=n;++i) insert(s[i]-'a');
	for(int i=2;i<=ptot;++i) G[nxt[i]].pb(i);
	dfs(1);
	for(int i=1,now=1,l=0;i<=m;++i){
		int c=t[i]-'a';
		while(now!=1&&!son[now][c]) now=nxt[now],l=len[now];
		if(son[now][c]) now=son[now][c],++l;
		if(l&&cnt[now]==1) a[i]=mp(len[nxt[now]]+1,l);
	}
	clear();
	for(int i=1;i<=m;++i) insert(t[i]-'a');
	for(int i=2;i<=ptot;++i) G[nxt[i]].pb(i);
	dfs(1);
	int ans=INF;
	for(int i=1,now=1,l=0;i<=m;++i){
		int c=t[i]-'a';
		while(now!=1&&!son[now][c]) now=nxt[now],l=len[now];
		if(son[now][c]) now=son[now][c],++l;
		if(cnt[now]==1){
			int l1=a[i].fi,r1=a[i].se,l2=len[nxt[now]]+1,r2=l;
			if(l1>l2) swap(l1,l2),swap(r1,r2);
			if(l2&&l2<=r1) chkmin(ans,l2);
		}
	}
	if(ans==INF) ans=-1;
	println(ans);
	return 0;
}

标签:nxt,int,题解,void,len,son,swap,Catch,Match
来源: https://www.cnblogs.com/winterfrost/p/cf427d-solution.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有