后缀数组模板

隐身守侯 提交于 2019-12-06 11:16:45

模板题

学了很久,算是解决了一块心病,
虽然大致能理解,但现在也只是停留在写模板的程度
存个模板先

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
using namespace std;
const int MAXN=1e6+10;
char s[MAXN];
int n,m,sa[MAXN],rk[MAXN],tp[MAXN],c[MAXN],height[MAXN];

void getsa(){
    m='z';
    for(int i=1;i<=n;i++) c[rk[i]=s[i]]++;
    for(int i=1;i<=m;i++) c[i]+=c[i-1];
    for(int i=n;i>=1;i--) sa[c[rk[i]]--]=i;
    for(int w=1,p=0;p<n;w<<=1,m=p){
        p=0;
        for(int i=n-w+1;i<=n;i++) tp[++p]=i;
        for(int i=1;i<=n;i++) if(sa[i]>w) tp[++p]=sa[i]-w;
        for(int i=1;i<=m;i++) c[i]=0;
        for(int i=1;i<=n;i++) c[rk[i]]++;
        for(int i=1;i<=m;i++) c[i]+=c[i-1];
        for(int i=n;i>=1;i--) sa[c[rk[tp[i]]]--]=tp[i];
        swap(rk,tp);
        rk[sa[1]]=p=1;
        for(int i=2;i<=n;i++)
            rk[sa[i]]=(tp[sa[i]]==tp[sa[i-1]]&&tp[sa[i]+w]==tp[sa[i-1]+w])?p:++p;
    }
}

void getheight(){
    int k=0;
    for(int i=1;i<=n;i++){
        if(rk[i]==1) continue;
        if(k) k--;
        int j=sa[rk[i]-1];
        while(i+k<=n&&j+k<=n&&s[i+k]==s[j+k]) k++;
        height[rk[i]]=k;
    }
}

int main(){
    scanf("%s",s+1);
    n=strlen(s+1);
    getsa();
    getheight();
    for(int i=1;i<=n;i++) printf("%d%c",sa[i]-1,i<n?' ':'\n');
    for(int i=1;i<=n;i++) printf("%d%c",height[i],i<n?' ':'\n');
    return 0;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!