您的位置:首页 > 其它

SPOJ lcs2 Longest Common Substring II 后缀自动机

2015-08-22 23:01 519 查看
题意:求n个串的最长公共子串(连续的)

方法:用其中一串构建后缀自动机,其它串来跑,并更新其len(step)即答案。

PS:本来是另一开一个数组来记录时间的,但状态转移时要用到SAM_node的标号,增加了时间复杂度常数,被卡了时间

#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <algorithm>
#include <iostream>
#include <math.h>
#include <string.h>
using namespace std;
typedef long long ll;
const int Mod=1e9+7;
const int N=1e5+5;
int n;
struct SAM_Node{
SAM_Node *fa,*next[26];
int len;
int pos,temp;
SAM_Node(){}
SAM_Node(int _len){
fa=0;len=_len;temp=0;
memset(next,0,sizeof(next));
}
};
SAM_Node SAM_node[N<<1],*SAM_root,*SAM_last,*b[N<<1];
int SAM_size;
SAM_Node *newSAM_Node(int len){
SAM_node[SAM_size]=SAM_Node(len);
SAM_node[SAM_size].pos=SAM_size;
return &SAM_node[SAM_size++];
}
SAM_Node *newSAM_Node(SAM_Node *p){
SAM_node[SAM_size]=*p;
SAM_node[SAM_size].pos=SAM_size;
return &SAM_node[SAM_size++];
}
void SAM_init(){
SAM_size=0;
SAM_root=SAM_last=newSAM_Node(0);
SAM_node[0].pos=0;
}
void SAM_add(int x,int len){
SAM_Node *p=SAM_last,*np=newSAM_Node(p->len+1);
SAM_last=np;
for(;p&&!p->next[x];p=p->fa)p->next[x]=np;
if(!p){
np->fa=SAM_root;
return;
}
SAM_Node *q=p->next[x];
if(q->len==p->len+1){
np->fa=q;
return;
}
//puts("3");
SAM_Node *nq=newSAM_Node(q);
nq->len=p->len+1;
q->fa=nq;
np->fa=nq;
for(;p&&p->next[x]==q;p=p->fa)p->next[x]=nq;
}
char a
;
int dp[N<<1];
int rank[N<<1],cnt[N<<1];
void Sort(){
memset(cnt,0,sizeof(cnt));
for(int i=0;i<SAM_size;i++)
cnt[SAM_node[i].len]++;
for(int i=1;i<=n;i++)
cnt[i]+=cnt[i-1];
for(int i=0;i<SAM_size;i++){
//rank[--cnt[SAM_node[i].len]]=i;
b[--cnt[SAM_node[i].len]]=&SAM_node[i];
}
}
void work(){
int T;
SAM_init();
scanf("%s",a+1);
n=strlen(a+1);
for(int i=1;i<=n;i++)
SAM_add(a[i]-'a',i);
Sort();
int ret=0;
//    for(int i=0;i<SAM_size;i++)
//        cnt[i]=SAM_node[i].len;
while(~scanf("%s",a+1)){
n=strlen(a+1);
SAM_Node *Cur=SAM_root;
int temp=0;
for(int i=1;i<=n;i++){
int u=a[i]-'a';
if(Cur->next[u]){
temp++;
Cur=Cur->next[u];
}
else{
while(true){
Cur=Cur->fa;
if(!Cur)break;
if(Cur->next[u])break;
}
if(!Cur){
Cur=SAM_root;temp=0;
}
else{
temp=Cur->len+1;
Cur=Cur->next[u];
}
}
//u=Cur->pos;
//dp[u]=max(dp[u],temp);
Cur->temp=max(Cur->temp,temp);
}
int u,v;
for(int i=SAM_size-1;i>0;i--){
//u=rank[i];
//v=SAM_node[u].fa->pos;
//dp[v]=max(dp[v],dp[u]);
//cnt[u]=min(cnt[u],dp[u]);
//dp[u]=0;

//u=b[i]->pos;v=b[i]->fa->pos;
//dp[v]=max(dp[v],dp[u]);
//b[i]->len=min(b[i]->len,dp[u]);
//dp[u]=0;
b[i]->fa->temp=max(b[i]->fa->temp,b[i]->temp);
b[i]->len=min(b[i]->len,b[i]->temp);
b[i]->temp=0;

}
}
for(int i=1;i<SAM_size;i++)
ret=max(ret,b[i]->len);
printf("%d\n",ret);
}
int main(){
freopen("data_in.txt","r",stdin);
//freopen("C_out.txt","w",stdout);
work();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: