• 后缀数组-倍增算法模板


    sa[i] 表示排名第i的是前缀str(sa[i]),  rank[i]表示前缀str(i)的排名。

    void build_sa(int m) {
        int *x = t, *y = t2;
        for(int i = 0; i < m; i ++) c[i] = 0;
        for(int i = 0; i < n; i ++) c[x[i]=s[i]] ++;
        for(int i = 1; i < m; i ++) c[i] += c[i-1];
        for(int i = n-1; i >= 0; i --) sa[--c[x[i]]] = i;
        for(int k = 1; k <= n; k <<= 1) {
            int p = 0;
            for(int i = n-k; i < n; i ++) y[p++] = i;
            for(int i = 0; i < n; i ++) if(sa[i] >= k) y[p++] = sa[i] - k;
            for(int i = 0; i < m; i ++) c[i] = 0;
            for(int i = 0; i < n; i ++) c[x[y[i]]]++;
            for(int i = 1; i < m; i ++) c[i] += c[i-1];
            for(int i = n-1; i >= 0; i --) sa[--c[x[y[i]]]] = y[i];
            swap(x,y);
            p = 1;
            x[sa[0]] = 0;
            for(int i = 1; i < n; i ++)
                x[sa[i]] = y[sa[i-1]] == y[sa[i]] && y[sa[i-1]+k] == y[sa[i]+k]?p-1:p++;
            if(p >= n)break;
            m = p;
        }
    }
    #define maxn 1000001
    int wa[maxn],wb[maxn],wv[maxn],ws[maxn];
    int cmp(int *r,int a,int b,int l) {
        return r[a]==r[b]&&r[a+l]==r[b+l];
    }
    void da(int *r,int *sa,int n,int m) {
         int i , j, p, *x = wa, *y = wb, *t;
         for(i = 0; i < m; i ++) ws[i] = 0;
         for(i = 0; i < n; i ++) ws[x[i] = r[i]]++;
         for(i = 1; i < m; i ++) ws[i] += ws[i-1];
         for(i = n-1; i >= 0; i --) sa[--ws[x[i]]] = i;
         for(j = 1, p = 1; p < n; j*=2,m = p) {
             for(p = 0, i = n-j; i < n; i ++) y[p++] = i;
             for(i = 0; i < n; i ++) if(sa[i] >= j) y[p++] = sa[i]-j;
             for(i = 0; i < n; i ++) wv[i] = x[y[i]];
             for(i = 0; i < m; i ++) ws[i] = 0;
             for(i = 0; i < n; i ++) ws[wv[i]]++;
             for(i = 1; i < m; i ++) ws[i] += ws[i-1];
             for(i = n-1; i >= 0; i --) sa[--ws[wv[i]]] = y[i];
             for(t = x, x = y, y = t, p = 1, x[sa[0]] = 0,i = 1; i < n; i ++)
             x[sa[i]] = cmp(y,sa[i-1],sa[i],j)?p-1:p++;
         }
         return;
    }
    int rank[maxn],height[maxn];
    void calheight(int *r,int *sa,int n) {
         int i,j,k=0;
         for(i = 1; i <= n; i ++) rank[sa[i]] = i;
         for(i = 0; i < n; height[rank[i++]] = k)
         for(k?k--:0, j = sa[rank[i]-1]; r[i+k]==r[j+k]; k++);
         return;
    }
    int RMQ[maxn];
    int mm[maxn];
    int best[20][maxn];
    void initRMQ(int n) {
         int i, j, a, b;
         for(mm[0] = -1, i = 1; i <= n; i ++)
         mm[i] = ((i&(i-1))==0)?mm[i-1]+1:mm[i-1];
         for(i = 1; i <= n; i ++) best[0][i] = i;
         for(i = 1; i <= mm[n]; i++)
         for(j = 1; j <= n+1-(1<<i);j++) {
           a = best[i-1][j];
           b = best[i-1][j+(1<<(i-1))];
           if(RMQ[a] < RMQ[b]) best[i][j] = a;
           else best[i][j] = b;
         }
         return;
    }
    int askRMQ(int a,int b) {
        int t;
        t = mm[b-a+1]; b -= (1<<t)-1;
        a = best[t][a]; b = best[t][b];
        return RMQ[a] < RMQ[b]?a:b;
    }
    int lcp(int a,int b) {
        int t;
        a = rank[a]; b = rank[b];
        if(a>b) {t=a;a=b;b=t;}
        return(height[askRMQ(a+1,b)]);
    }
    
    
    
  • 相关阅读:
    C语言I博客作业02
    C语言I—2019秋作业01
    C语言I作业10
    C语言I作业09
    C语言I作业08
    C语言I作业07
    C语言I|作业06
    C语言I作业05
    C语言I作业004:第八周作业
    c语言|作业003
  • 原文地址:https://www.cnblogs.com/xingkongyihao/p/7257481.html
Copyright © 2020-2023  润新知