后缀数组模板

来源:互联网 发布:淘宝指数在哪里看 编辑:程序博客网 时间:2024/04/28 01:45
#include<iostream>#include<algorithm>#include<cstdlib>#include<cstdio>#include<cstring>#include<vector>#include<cmath>#include<complex>#include<queue>using namespace std;const int MAXN=1e5+10;char s[MAXN];int t1[MAXN],t2[MAXN],cc[MAXN],x[MAXN],sa[MAXN],Rank[MAXN],height[MAXN],Min[MAXN][50],kkk;int len;bool cmp(int *y,int a,int b,int k){    int a1=y[a];    int b1=y[b];    int a2=a+k>=len ? -1:y[a+k];    int b2=b+k>=len ? -1:y[b+k];    return a1==b1 && a2==b2;}int make_sa(){    int *x=t1,*y=t2;    int m=26;    for(int i=0; i<m; i++) cc[i]=0;    for(int i=0; i<len; i++) ++cc[x[i]=s[i]-'a'];    for(int i=1; i<m; i++) cc[i]+=cc[i-1];    for(int i=len-1; i>=0; i--) sa[--cc[x[i]]]=i;    for(int k=1; k<=len; k<<=1)    {        int p=0;        for(int i=len-k; i<len; i++) y[p++]=i;        for(int i=0; i<len; i++)            if( sa[i]>=k ) y[p++]=sa[i]-k;        for(int i=0; i<m; i++) cc[i]=0;        for(int i=0; i<len; i++) ++cc[x[y[i]]];        for(int i=1; i<m; i++) cc[i]+=cc[i-1];        for(int i=len-1; i>=0; i--) sa[--cc[x[y[i]]]]=y[i];        swap(x,y);        m=1;        x[sa[0]]=0;        for(int i=1; i<len; i++)            x[sa[i]]=cmp(y,sa[i],sa[i-1],k) ? m-1:m++;        if( m>=len ) break;    }}void make_height(){    for(int i=0; i<len; i++) Rank[sa[i]]=i;    height[0]=0;    int k=0;    for(int i=0; i<len; i++)    {        if(!Rank[i]) continue;        int j=sa[Rank[i]-1];        if(k) k--;        while(s[i+k]==s[j+k]) k++;        height[Rank[i]]=k;    }}int main(){    scanf("%d %s",&s);    len=strlen(s);    make_sa();    make_height();}

原创粉丝点击