后缀数组 倍增算法

来源:互联网 发布:aerial mac 不能播放 编辑:程序博客网 时间:2024/05/01 06:23
/* 后缀数组 倍增法 sa[i]表示从字符串sa[i]开始的后缀数组,排列第i S[sa[i]]<S[sa[i+1]] ran[i]表示从i下标开始的后缀数组,从小到大排列的名次*/#include<iostream>#include<cstdio>#include<algorithm>#include<vector>#include<cstring>#include<cmath>using namespace std;typedef long long LL;const int maxn = 10000+10;int sa[maxn];int tmp[maxn];int ran[maxn];int n, k;bool cmp(const int& i,const int& j) {    if(ran[i] != ran[j])        return ran[i]<ran[j];    else {        int ri = i+k<=n?ran[i+k]:-1;        int rj = j+k<=n?ran[j+k]:-1;        return ri<rj;    }}void construct_sa(string s) {    n = (int)s.size();    for (int i=0; i<=n; i++) {        sa[i] = i;        ran[i] = i==n?-1:s[i];    }    for (k=1; k<=n; k*=2) {        sort(sa, sa+n+1, cmp);        tmp[sa[0]] = 0;        for (int i=1; i<=n; i++)            tmp[sa[i]] = tmp[sa[i-1]]+(cmp(sa[i-1], sa[i])?1:0);        for (int i=0; i<=n; i++)            ran[i] = tmp[i];    }}int main() {    string s;    cin>>s;    construct_sa(s);    return 0;}
0 0