SA後綴數組模板

下標都是從1開始的

計數排序

const int N=100010;
#define MS(x,y) memset(x,y,sizeof(x))
int sa[N],rnk[N],height[N],tax[N],tp[N],n,m,k;
char str[N];
void rsort()
{
    for(int i=0;i<=m;i++) tax[i]=0;
    for(int i=1;i<=n;i++) tax[rnk[tp[i]]]++;
    for(int i=1;i<=m;i++) tax[i]+=tax[i-1];
    for(int i=n;i>=1;i--) sa[tax[rnk[tp[i]]]--]=tp[i];
}
int cmp(int *f,int x,int y,int w) {return f[x]==f[y]&&f[x+w]==f[y+w];}
void suffix()
{
    MS(tax,0);MS(rnk,0);MS(sa,0);MS(height,0);MS(tp,0);
    for(int i=1;i<=n;i++) rnk[i]=str[i],tp[i]=i;
    m=127,rsort();
    for(int w=1,p=1,i;p<n;w+=w,m=p)
    {
        for(p=0,i=n-w+1;i<=n;i++) tp[++p]=i;
        for(i=1;i<=n;i++) if(sa[i]>w) tp[++p]=sa[i]-w;
        rsort(),swap(rnk,tp),rnk[sa[1]]=p=1;
        for(i=2;i<=n;i++) rnk[sa[i]]=cmp(tp,sa[i],sa[i-1],w)?p:++p;
    }
    int j,k=0;
    for(int i=1;i<=n;height[rnk[i++]]=k)
        for(k=k?k-1:k,j=sa[rnk[i]-1];str[i+k]==str[j+k];k++);
}

快速排序

const int N=100010;
#define MS(x,y) memset(x,y,sizeof(x))
struct node
{
    int x,id;
    bool operator < (const node &t) const{
        if(x==t.x) return id<t.id;
        return x<t.x;
    }
}r[N];
int sa[N],rnk[N],tax[N],tp[N],height[N],n,m;
int str[N];
void rsort()
{
    int i;
    for(i=1;i<=m;i++) tax[i]=0;
    for(i=1;i<=n;i++) tax[rnk[tp[i]]]++;
    for(i=1;i<=m;i++) tax[i]+=tax[i-1];
    for(i=n;i>=1;i--) sa[tax[rnk[tp[i]]]--]=tp[i];
}
int cmp(int* f,int a,int b,int l) {return f[a]==f[b]&&f[a+l]==f[b+l];}
void suffix()
{
    MS(tax,0);MS(rnk,0);MS(sa,0);MS(height,0);MS(tp,0);
    int i,j,k=0,w,p;m=1;
    for(i=1;i<=n;i++) r[i].id=i,r[i].x=str[i];
    sort(r+1,r+1+n);
    for(i=1;i<=n;i++) sa[i]=r[i].id;
    for(i=2,rnk[sa[1]]=1;i<=n;i++) rnk[sa[i]]=(r[i].x==r[i-1].x)?m:++m;
    for(p=1,w=1;p<n;w+=w,m=p)
    {
        for(p=0,i=n-w+1;i<=n;i++) tp[++p]=i;
        for(i=1;i<=n;i++) if(sa[i]>w) tp[++p]=sa[i]-w;
        rsort(),swap(rnk,tp),rnk[sa[1]]=1;
        for(p=1,i=2;i<=n;i++) rnk[sa[i]]=cmp(tp,sa[i],sa[i-1],w)?p:++p;
    }
    for(i=1;i<=n;height[rnk[i++]]=k)
        for(k=k?k-1:k,j=sa[rnk[i]-1];str[i+k]==str[j+k];k++);
}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章