您的位置:首页 > 其它

BZOJ 2946 SA/SAM

2017-04-26 21:07 148 查看

思路:

1. 二分+后缀数组

2.SAM

//By SiriusRen
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=22222;
int n,num,cntA
,cntB
,A
,B
,sa
,rk
,tsa
,ht
,rec
,vis[10];
char ch[5555],s
;
void SA(){
for(int i=1;i<=n;i++)cntA[s[i]]++;
for(int i=1;i<=256;i++)cntA[i]+=cntA[i-1];
for(int i=n;i;i--)sa[cntA[s[i]]--]=i;
rk[sa[1]]=1;
for(int i=2;i<=n;i++)rk[sa[i]]=rk[sa[i-1]]+(s[sa[i]]!=s[sa[i-1]]);
for(int l=1;rk[sa
]<n;l<<=1){
memset(cntA,0,sizeof(cntA));
memset(cntB,0,sizeof(cntB));
for(int i=1;i<=n;i++)
cntA[A[i]=rk[i]]++,
cntB[B[i]=i+l<=n?rk[i+l]:0]++;
for(int i=1;i<=n;i++)cntA[i]+=cntA[i-1],cntB[i]+=cntB[i-1];
for(int i=n;i;i--)tsa[cntB[B[i]]--]=i;
for(int i=n;i;i--)sa[cntA[A[tsa[i]]]--]=tsa[i];
rk[sa[1]]=1;
for(int i=2;i<=n;i++)
rk[sa[i]]=rk[sa[i-1]]+(A[sa[i]]!=A[sa[i-1]]||B[sa[i]]!=B[sa[i-1]]);
}
for(int i=1,j=0;i<=n;i++){
j=j?j-1:0;
while(s[i+j]==s[sa[rk[i]-1]+j])j++;
ht[rk[i]]=j;
}
}
bool check(int mid){
int cnt=0;
for(int i=1;i<=n;i++){
if(ht[i]<mid)memset(vis,0,sizeof(vis)),cnt=0;
else{
if(!vis[rec[sa[i]]])vis[rec[sa[i]]]=1,cnt++;
if(!vis[rec[sa[i-1]]])vis[rec[sa[i-1]]]=1,cnt++;
}
if(cnt>=num)return 1;
}return 0;
}
int main(){
scanf("%d",&num);
for(int i=1;i<=num;i++){
scanf("%s",ch+1);
int templen=strlen(ch+1);
for(int j=1;j<=templen;j++)s[++n]=ch[j],rec
=i;
s[++n]=i;
}SA();
int l=0,r=n,ans=0;
while(l<=r){
int mid=(l+r)>>1;
if(check(mid))ans=mid,l=mid+1;
else r=mid-1;
}printf("%d\n",ans);
}

 

//By SiriusRen
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=4050;
int n,m;char s
;
struct SAM{
int ch
[26],fa
,dis
,root,last,tot,ans
,v
,q
,maxx
;
void init(){root=last=tot=1;}
int newnode(int v){return dis[++tot]=v,tot;}
void add(int x){
int p=last,np=newnode(dis

+1);last=np; for(;p&&!ch[p][x];p=fa[p])ch[p][x]=np; if(!p)fa[np]=root; else{ int q=ch[p][x]; if(dis[q]==dis[p]+1)fa[np]=q; else{ int nq=newnode(dis[p]+1); memcpy(ch[nq],ch[q],sizeof(ch[q])); fa[nq]=fa[q],fa[np]=fa[q]=nq; for(;ch[p][x]==q;p=fa[p])ch[p][x]=nq; } } } void topsort(){ for(int i=1;i<=tot;i++)ans[i]=dis[i],v[dis[i]]++; for(int i=1;i<=tot;i++)v[i]+=v[i-1]; for(int i=tot;i;i--)q[v[dis[i]]--]=i; } void solve(){ memset(maxx,0,sizeof(maxx)); scanf("%s",s),n=strlen(s); int p=root,len=0; for(int i=0;i<n;i++){ int x=s[i]-'a'; if(ch[p][x])len++,p=ch[p][x]; else{ for(;p&&!ch[p][x];p=fa[p]); if(!p)p=root,len=0; else len=dis[p]+1,p=ch[p][x]; }maxx[p]=max(maxx[p],len); } for(int i=tot;i;i--){ int x=q[i]; ans[x]=min(ans[x],maxx[x]); if(maxx[x]&&fa[x])maxx[fa[x]]=max(maxx[fa[x]],dis[fa[x]]); } } }T; int main(){ T.init(); scanf("%d%s",&m,s),n=strlen(s); for(int i=0;i<n;i++)T.add(s[i]-'a'); T.topsort(); for(int i=1;i<m;i++)T.solve(); for(int i=1;i<=T.tot;i++)T.ans[1]=max(T.ans[1],T.ans[i]); printf("%d\n",T.ans[1]); }

[p] 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: