BZOJ4032: [HEOI2015]最短不公共子串(后缀自动机+序列自动机)

题目描述

在虐各种最长公共子串、子序列的题虐的不耐烦了之后,你决定反其道而行之。

一个串的“子串”指的是它的连续的一段,例如bcd是abcdef的子串,但bde不是。

一个串的“子序列”指的是它的可以不连续的一段,例如bde是abcdef的子串,但bdd不是。

下面,给两个小写字母串A,B,请你计算:

(1) A的一个最短的子串,它不是B的子串

(2) A的一个最短的子串,它不是B的子序列

(3) A的一个最短的子序列,它不是B的子串

(4) A的一个最短的子序列,它不是B的子序列

输入输出格式

输入格式:

有两行,每行一个小写字母组成的字符串,分别代表A和B。

输出格式:

输出4行,每行一个整数,表示以上4个问题的答案的长度。如果没有符合要求的答案,输出-1.

输入输出样例

输入样例#1: 复制
aabbcc
abcabc
输出样例#1: 复制
2
4
2
4
输入样例#2: 复制
aabbcc
aabbcc
输出样例#2: 复制
-1
-1
2
-1

说明

对于20%的数据,A和B的长度都不超过20

对于50%的数据,A和B的长度都不超过500

对于100%的数据,A和B的长度都不超过2000

题解

  这题好烦……

  据说还有大佬是用dp的方法做的……相当于做了四道题……先膜为敬……

  然后看到有大佬是直接建上后缀自动机和回文自动机,然后在上面跑BFS,如果跑不动了就返回答案,可以保证最优

  然后我因为一堆sb错误调了一个多小时……

  为啥取队头元素不能直接整个结构体取啊!为啥我SAM都能打错啊!

  1 //minamoto
  2 #include<cstring>
  3 #include<algorithm>
  4 #include<iostream>
  5 #include<cstdio>
  6 #include<queue>
  7 using namespace std;
  8 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
  9 char buf[1<<21],*p1=buf,*p2=buf;
 10 char sr[1<<21],z[20];int C=-1,Z;
 11 inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
 12 inline void print(int x){
 13     if(C>1<<20)Ot();if(x<0)sr[++C]=45,x=-x;
 14     while(z[++Z]=x%10+48,x/=10);
 15     while(sr[++C]=z[Z],--Z);sr[++C]='
';
 16 }
 17 const int N=4005;
 18 struct SAM{
 19     int fa[N],ch[N][26],l[N];int last,cnt;
 20     SAM(){last=cnt=1;}
 21     void ins(int c){
 22         int p=last,np=++cnt;last=np,l[np]=l[p]+1;
 23         for(;p&&!ch[p][c];p=fa[p]) ch[p][c]=np;
 24         if(!p) fa[np]=1;
 25         else{
 26             int q=ch[p][c];
 27             if(l[q]==l[p]+1) fa[np]=q;
 28             else{
 29                 int nq=++cnt;l[nq]=l[p]+1;
 30                 memcpy(ch[nq],ch[q],sizeof(ch[q]));
 31                 fa[nq]=fa[q],fa[q]=fa[np]=nq;
 32                 for(;ch[p][c]==q;p=fa[p]) ch[p][c]=nq;
 33             }
 34         }
 35     }
 36 }SA,SB;
 37 struct SqAM{
 38     int ch[N][26],lst[26],fa[N];
 39     int root,cnt;
 40     SqAM(){root=cnt=1;for(int i=0;i<26;++i) lst[i]=1;}
 41     void ins(int c){
 42         int p=lst[c],np=++cnt;
 43         fa[np]=p;
 44         for(int i=0;i<26;++i)
 45         for(int j=lst[i];j&&!ch[j][c];j=fa[j])
 46         ch[j][c]=np;
 47         lst[c]=np;
 48     }
 49 }SQA,SQB;
 50 struct node{
 51     int a,b,step;
 52     node(int a=0,int b=0,int step=0):a(a),b(b),step(step){}
 53 };
 54 int vis[N][N];
 55 int bfs1(){
 56     queue<node> q;
 57     q.push(node(1,1,0));
 58     vis[1][1]=1;
 59     while(!q.empty()){
 60         int ra=q.front().a,rb=q.front().b,st=q.front().step;
 61         for(int i=0;i<26;i++){
 62             int va=SA.ch[ra][i],vb=SB.ch[rb][i];
 63             if(va&&vb){
 64                 if(vis[va][vb]==1) continue;
 65                 q.push(node(va,vb,st+1));
 66                 vis[va][vb]=1;
 67             }
 68             if(va&&!vb) return st+1;
 69         }
 70         q.pop();
 71     }
 72     return -1;
 73 }
 74 int bfs2(){
 75     queue<node> q;
 76     q.push(node(1,1,0));
 77     vis[1][1]=2;
 78     while(!q.empty()){
 79         int ra=q.front().a,rb=q.front().b,st=q.front().step;
 80         for(int i=0;i<26;i++){
 81             int va=SA.ch[ra][i],vb=SQB.ch[rb][i];
 82             if(va&&vb){
 83                 if(vis[va][vb]==2) continue;
 84                 q.push(node(va,vb,st+1));
 85                 vis[va][vb]=2;
 86             }
 87             if(va&&!vb) return st+1;
 88         }
 89         q.pop();
 90     }
 91     return -1;
 92 }
 93 int bfs3(){
 94     queue<node> q;
 95     q.push(node(1,1,0));
 96     vis[1][1]=3;
 97     while(!q.empty()){
 98         int ra=q.front().a,rb=q.front().b,st=q.front().step;
 99         for(int i=0;i<26;i++){
100             int va=SQA.ch[ra][i],vb=SB.ch[rb][i];
101             if(va&&vb){
102                 if(vis[va][vb]==3) continue;
103                 q.push(node(va,vb,st+1));
104                 vis[va][vb]=3;
105             }
106             if(va&&!vb) return st+1;
107         }
108         q.pop();
109     }
110     return -1;
111 }
112 int bfs4(){
113     queue<node> q;
114     q.push(node(1,1,0));
115     vis[1][1]=4;
116     while(!q.empty()){
117         int ra=q.front().a,rb=q.front().b,st=q.front().step;
118         for(int i=0;i<26;i++){
119             int va=SQA.ch[ra][i],vb=SQB.ch[rb][i];
120             if(va&&vb){
121                 if(vis[va][vb]==4) continue;
122                 q.push(node(va,vb,st+1));
123                 vis[va][vb]=4;
124             }
125             if(va&&!vb) return st+1;
126         }
127         q.pop();
128     }
129     return -1;
130 }
131 char a[N],b[N];int tot1,tot2;char ch;
132 int main(){
133     scanf("%s%s",a+1,b+1);
134     tot1=strlen(a+1),tot2=strlen(b+1);
135     for(int i=1;i<=tot1;++i) SA.ins(a[i]-'a'),SQA.ins(a[i]-'a');
136     for(int i=1;i<=tot2;++i) SB.ins(b[i]-'a'),SQB.ins(b[i]-'a');
137     printf("%d
%d
%d
%d
",bfs1(),bfs2(),bfs3(),bfs4());
138     return 0;
139 }
原文地址:https://www.cnblogs.com/bztMinamoto/p/9471155.html