luoguP4112 [HEOI2015]最短不公共子串

链接

luogu

loj

思路

子串可以用后缀自动机,子序列可以用序列自动机。

序列自动机是啥,就是能访问到所有子序列的自动机。

每个点记录下一个字母最近出现的位置。不过我这里构造是\(O(n^2)\)。

然后进行bfs进行广搜就行了。

注意vis[][]剪枝,要不TLE。

代码

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N=2000+7;
int n,m;
struct node {
int len,fa,ch[26];
}dian[4][N<<1];
int las[4]={1,1,1,1},tot[4]={1,1,1,1};
void add(int c,int who) {
int p=las[who];int np=las[who]=++tot[who];
dian[who][np].len=dian[who][p].len+1;
for(;p&&!dian[who][p].ch[c];p=dian[who][p].fa) dian[who][p].ch[c]=np;
if(!p) dian[who][np].fa=1;
else {
int q=dian[who][p].ch[c];
if(dian[who][q].len==dian[who][p].len+1) dian[who][np].fa=q;
else {
int nq=++tot[who];
dian[who][nq]=dian[who][q];
dian[who][nq].len=dian[who][p].len+1;
dian[who][q].fa=dian[who][np].fa=nq;
for(;p&&dian[who][p].ch[c]==q;p=dian[who][p].fa)
dian[who][p].ch[c]=nq;
}
}
}
struct edge{char s[N];}a,b;
int vis[N<<1][N<<1],flag;
void bfs(int T_T,int QwQ) {
queue<pair<pair<int,int>,int> > q;
q.push(make_pair(make_pair(1,1),1));
while(!q.empty()) {
pair<pair<int,int>,int> u=q.front();
node lj1=dian[T_T][u.first.first],lj2=dian[QwQ][u.first.second];
q.pop();
for(int i=0;i<26;++i) {
if(lj1.ch[i]&&!lj2.ch[i])
return printf("%d\n",u.second),void();
if(lj1.ch[i]&&lj2.ch[i]&&vis[lj1.ch[i]][lj2.ch[i]]!=flag) {
q.push(make_pair(make_pair(lj1.ch[i],lj2.ch[i]),u.second+1));
vis[lj1.ch[i]][lj2.ch[i]]=flag;
}
}
}
puts("-1");
}
int main() {
scanf("%s%s",a.s,b.s);
n=strlen(a.s),m=strlen(b.s);
for(int i=0;i<n;++i) add(a.s[i]-'a',0);
for(int i=0;i<m;++i) add(b.s[i]-'a',1);
//build a
for(int i=0;i<n;++i)
if(!dian[2][1].ch[a.s[i]-'a'])
dian[2][1].ch[a.s[i]-'a']=i+2;
for(int i=0;i<n;++i)
for(int j=i+1;j<n;++j)
if(!dian[2][i+2].ch[a.s[j]-'a'])
dian[2][i+2].ch[a.s[j]-'a']=j+2;
//build b
for(int i=0;i<m;++i)
if(!dian[3][1].ch[b.s[i]-'a'])
dian[3][1].ch[b.s[i]-'a']=i+2;
for(int i=0;i<m;++i)
for(int j=i+1;j<m;++j)
if(!dian[3][i+2].ch[b.s[j]-'a'])
dian[3][i+2].ch[b.s[j]-'a']=j+2;
flag++,bfs(0,1);
flag++,bfs(0,3);
flag++,bfs(2,1);
flag++,bfs(2,3);
return 0;
}

最新文章

  1. Sphinx的配置和使用
  2. 装个蒜。学习下dispatch queue
  3. HTML5播放器实例
  4. flex lineChart 显示所有的数据节点
  5. [android] 手机卫士设置向导页面
  6. Java基础-ArrayList和LinkedList的区别
  7. android TP驱动移植调试笔记(转)
  8. MinGW GCC下sleep()函数问题
  9. HDU2037 今年暑假不AC 贪心算法
  10. 充分利用CPU高速缓存,提高程序效率(原理篇)
  11. 将node-expat扩展编译至node.exe中
  12. adb概览及协议参考
  13. 开发者所需要知道的iOS7 SDK新特性
  14. hdu_5806_NanoApe Loves Sequence Ⅱ(双指针)
  15. 百度和谷歌的逆地址解析及GPS、谷歌地图和百度地图坐标之间的转换(python版)
  16. mac 使用iTerm2快捷登录远程服务器
  17. Python学习(二十四)—— 前端基础之Bookstrap
  18. ORCAl存储过程
  19. $.contains(a,b)
  20. python学习之老男孩python全栈第九期_day004知识点总结

热门文章

  1. Kafka Streams的Data Types and Serialization
  2. 3、Vue实例的属性
  3. C# vb .net图像合成-合成自定义路径
  4. rsync+inotify实现多台服务器之间数据实时同步
  5. Date+闭包
  6. 浅谈HTML5的新特性
  7. android中listview滑动卡顿的原因
  8. grub破解和bios加密
  9. react的事件处理为什么要bind this 改变this的指向?
  10. Maven插件Jib配合Harbor生成Docker镜像