后缀数组模板

转自 学长


template 
struct suffixarray
{
    int str[LEN*3],sa[LEN*3];
    int rank[LEN],height[LEN];
    int id[LEN];
    int best[LEN][20];
    int len;
    bool equal(int *str, int a, int b)
    {
        return str[a]==str[b]&&str[a+1]==str[b+1]&&str[a+2]==str[b+2];
    }
    bool cmp3(int *str, int *nstr, int a, int b)
    {
        if(str[a]!=str[b])     return str[a]=0;--i) res[--id[str[sa[i]]]]=sa[i];
    }
    void dc3(int *str, int *sa, int n, int m)
    {
        #define F(x) ((x)/3+((x)%3==1?0:one))
        #define G(x) ((x)=len||(i=k)y[j++]=sa[i]-k;
            radixsort(x,y,sa,n,m);
            swap(x,y);
            /** 通过当前结果得到新字符串*/
            x[sa[0]]=num++;
            for(i=1;ib)swap(a,b);
        return RMQ(a,b);
    }
};



/******************************************************************
**  后缀数组 Suffix Array
**  INIT:solver.call_fun(char* s);
**  CALL: solver.lcp(int i,int j); //后缀i与后缀j的最长公共前缀
**  SP_USE: solver.LCS(char *s1,char* s2); //最长公共字串
******************************************************************/
struct SuffixArray{
    int r[maxn];
    int sa[maxn],rank[maxn],height[maxn];
    int t[maxn],t2[maxn],c[maxn],n;
    int m;//模板长度
    void init(char* s){
        n=strlen(s);
        for (int i=0;i=0;i--) sa[--c[x[i]]]=i;
        for (k=1,p=1;k=k) y[p++]=sa[i]-k;
            for (i=0;i=0;i--) sa[--c[x[y[i]]]]=y[i];
            swap(x,y);
            p=1;
            x[sa[0]]=0;
            for (i=1;irank[j]) swap(i,j);
        return RMQ(rank[i]+1,rank[j]);
    }
    void call_fun(char* s){
        init(s);//初始化后缀数组
        build_sa();//构造后缀数组sa
        getHeight();//计算height与rank
        LCP_init();//初始化RMQ
    }
    int LCS(char* s1,char* s2){
        int p,ans;
        int l=strlen(s1);
        p=l;
        s1[l]='$';
        s1[l+1]='\0';
        strcat(s1,s2);
        call_fun(s1);
        ans=0;
        for (int i=2;i<=n;i++)
            if ((sa[i-1]p)||(sa[i-1]>p&&sa[i]


你可能感兴趣的:(字符串处理,学习资料)