记录编号 |
382265 |
评测结果 |
AAAAAAAAAA |
题目名称 |
[HEOI 2015]最短不公共子串 |
最终得分 |
100 |
用户昵称 |
ONCE AGAIN |
是否通过 |
通过 |
代码语言 |
C++ |
运行时间 |
0.174 s |
提交时间 |
2017-03-13 16:33:34 |
内存使用 |
63.38 MiB |
显示代码纯文本
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int SIZEN = 4010;
char s1[SIZEN]={0},s2[SIZEN]={0};
int len1,len2;
struct Suffix_AutoMaton{
int ch[SIZEN][26];
int fail[SIZEN];
int val[SIZEN];
int sum[SIZEN];
int ws[SIZEN];
int Rank[SIZEN];
int node,now,temp;
Suffix_AutoMaton(){node = now = 1;memset(sum,0,sizeof sum);}
int NewNode(int v,int f){
val[++node] = v;
fail[node] = f;
return node;
}
void add(int c){
int curnode =NewNode(val[now]+1,0);
for(temp=now;temp&&!ch[temp][c];temp=fail[temp])ch[temp][c]=curnode;
if(!temp)fail[curnode] = 1;
else{
int p = ch[temp][c];
if(val[p] == val[temp]+1)fail[curnode] = p;
else{
int newnode = NewNode(val[temp]+1,fail[p]);
memcpy(ch[newnode],ch[p],sizeof ch[p]);
fail[p] = fail[curnode] = newnode;
for(;temp&&ch[temp][c]==p;temp=fail[temp])ch[temp][c]=newnode;
}
}
now = curnode;
}
void getrank(){
for(int i = 1;i <= node;i++)ws[val[i]]++;
for(int i = 1;i <= node;i++)ws[i] += ws[i-1];
for(int i = node;i >= 1;i--)Rank[ws[val[i]]--] = i;
}
void build(char *r,int n){
for(int i = 0;i < n;i++)add(r[i]-'a');
getrank();
}
int match(char *r,int n){
now = 1;int len = 0;
for(int i = 0;i < n;i++){
int c = r[i]-'a';
if(ch[now][c]){now = ch[now][c];len++;}
else {
for(;now&&!ch[now][c];now=fail[now]);
if(!now){now = 1;len = 0;}
else {len = val[now]+1;now=ch[now][c];}
}
sum[now] = max(sum[now],len);
}
int ans = 0x3f3f3f3f;
for(int i = node;i>=1;i--){
int x = Rank[i];
sum[fail[x]] = max(min(sum[x],val[fail[x]]),sum[fail[x]]);
}
//for(int i = 1;i <= node;i++)printf("%d ",sum[i]);printf("\n");
//for(int i = 1;i <= node;i++)printf("%d ",val[i]);printf("\n");
for(int i = 2;i <= node;i++){
if(sum[i] > val[fail[i]] && sum[i] < val[i])
ans = min(ans,sum[i]+1);
if(!sum[i])ans = min(ans,val[fail[i]]+1);
}
return ans == 0x3f3f3f3f?-1:ans;
}
void Print(){
printf("Suffix_AutoMaton : \n");
for(int i = 0;i <= node;i++){
printf("node = %d :",i);
for(int j = 0;j < 26;j++)printf("%d ",ch[i][j]);
printf("\n");
}
}
}A,B;
struct Sequence_AutoMaton{
int ch[SIZEN][26];
int near[26];
int node;
Sequence_AutoMaton(){memset(ch,0,sizeof ch);}
void build(char *r,int n){
for(int i = n;i>=0;i--){
for(int j = 0;j < 26;j++)ch[i][j] = near[j];
if(i)near[r[i-1]-'a'] = i;
}
node = n;
}
int match(char *r,int x,int y){
int now = 0;
for(int i = x;i <= y;i++){
int c = r[i]-'a';
if(ch[now][c])now=ch[now][c];
else return i-x+1;
}
return 0x3f3f3f3f;
}
void Print(){
printf("Sequence_AutoMaton : \n");
for(int i = 0;i <= node;i++){
printf("node = %d :",i);
for(int j = 0;j < 26;j++)printf("%d ",ch[i][j]);
printf("\n");
}
}
}AA,BB;
void SubTeskOne(){
printf("%d\n",A.match(s2,len2));
}
void SubTeskTwo(){
int ans = 0x3f3f3f3f;
for(int i = 0;i < len1;i++)
ans = min(ans,BB.match(s1,i,len1-1));
printf("%d\n",ans == 0x3f3f3f3f?-1:ans);
}
bool flag = true;
int F[SIZEN][SIZEN]={0};
void DFS1(int seq,int suf,int x){
if(!flag||!x)return;
for(int i = 0;i < 26&&flag;i++){
if(AA.ch[seq][i]&&B.ch[suf][i])DFS1(AA.ch[seq][i],B.ch[suf][i],x-1);
else if(AA.ch[seq][i]&&!B.ch[suf][i])flag = false;
}
}
void SubTeskThree(){
int l = 1,r = min(len1,len2),mid,ans = 0x3f3f3f3f;
while(l <= r){
mid = (l+r)>>1;
flag = true;
DFS1(0,1,mid);//Seq Suf
if(flag == true)l = mid+1;
else r = mid-1,ans = min(ans,mid);
}
printf("%d\n",ans == 0x3f3f3f3f?-1:ans);
}
int ans = 0x3f3f3f3f;
void DFS(int now1,int now2,int len){
// if(len > ans)return;
if(F[now1][now2]){ans = min(ans,len+F[now1][now2]);return;}
F[now1][now2] = 0x3f3f3f3f;
for(int i = 0;i < 26;i++){
if(!AA.ch[now1][i])continue;
if(!BB.ch[now2][i]){
ans = min(ans,len+1);
F[now1][now2] = 1;
}
else {
DFS(AA.ch[now1][i],BB.ch[now2][i],len+1);
if(F[AA.ch[now1][i]][BB.ch[now2][i]])
F[now1][now2] = min(F[now1][now2],F[AA.ch[now1][i]][BB.ch[now2][i]]+1);
}
}
}
void SubTeskFour(){
DFS(0,0,0);
printf("%d\n",ans == 0x3f3f3f3f?-1:ans);
}
int main(){
freopen("sus.in","r",stdin);
freopen("sus.out","w",stdout);
scanf("%s%s",s1,s2);
len1 = strlen(s1),len2 = strlen(s2);
//printf("%d %d\n",len1,len2);
A.build(s1,len1);B.build(s2,len2);
AA.build(s1,len1);BB.build(s2,len2);
//AA.Print();
//B.Print();
SubTeskOne();
SubTeskTwo();
SubTeskThree();
SubTeskFour();
return 0;
}