zoukankan      html  css  js  c++  java
  • 后缀数组模板/LCP模板

     1 //后缀数组模板,MANX为数组的大小
     2 //支持的操作有计算后缀数组(sa数组), 计算相邻两元素的最长公共前缀(height数组),使用get_height();
     3 //计算两个后缀a, 和b的最长公共前缀,请先使用lcp_init(),再调用get_lcp(a, b)得到
     4 //下面的n是输入字符串的长度+1(n = strlen(s) + 1), m是模板的范围 m=128表示在字母,数字范围内,可以扩大也可缩小
     5 //s[len] 是插入的一个比输入字符都要小的字符
     6 struct SufArray {
     7     char s[MAXN];
     8     int sa[MAXN], t[MAXN], t2[MAXN], c[MAXN], n, m;
     9     int rnk[MAXN], height[MAXN];//rnk和height数组
    10     int mi[MAXN][20], idxK[MAXN];//用于计算LCP
    11 
    12     void init() {
    13         mem0(s);
    14         mem0(height);
    15     }
    16     //读入字符串作为输入
    17     void read_str() {
    18         gets(s);
    19         m = 128;
    20         n = strlen(s);
    21         s[n++] = ' ';
    22     }
    23     void build_sa() {
    24         int *x = t, *y = t2;
    25         rep (i, 0, m - 1) c[i] = 0;
    26         rep (i, 0, n - 1) c[x[i] = s[i]] ++;
    27         rep (i, 1, m - 1) c[i] += c[i - 1];
    28         dec (i, n - 1, 0) sa[--c[x[i]]] = i;
    29         for(int k = 1; k <= n; k <<= 1) {
    30             int p = 0;
    31             rep (i, n - k, n - 1) y[p++] = i;
    32             rep (i, 0, n - 1) if(sa[i] >= k) y[p++] = sa[i] - k;
    33             rep (i, 0, m - 1) c[i] = 0;
    34             rep (i, 0, n - 1) c[x[y[i]]] ++;
    35             rep (i, 0, m - 1) c[i] += c[i - 1];
    36             dec (i, n - 1, 0) sa[--c[x[y[i]]]] = y[i];
    37             swap(x, y);
    38             p = 1;
    39             x[sa[0]] = 0;
    40             rep (i, 1, n - 1) {
    41                 x[sa[i]] = y[sa[i - 1]] == y[sa[i]] && y[sa[i - 1] + k] == y[sa[i] + k] ? p - 1 : p++;
    42             }
    43             if(p >= n) break;
    44             m = p;
    45         }
    46     }
    47     void get_height() {
    48         int k = 0;
    49         rep (i, 0, n - 1) rnk[sa[i]] = i;
    50         rep (i, 0, n - 1) {
    51             if(k) k --;
    52             int j = sa[rnk[i] - 1];
    53             while(s[i + k] == s[j + k]) k ++;
    54             height[rnk[i]] = k;
    55         }
    56     }
    57     void rmq_init(int *a, int n) {
    58         rep (i, 0, n - 1) mi[i][0] = a[i];
    59         for(int j = 1; (1 << j) <= n; j ++) {
    60             for(int i = 0; i + (1<<j) - 1 < n; i ++) {
    61                 mi[i][j] = min(mi[i][j - 1], mi[i + (1 << (j - 1))][j - 1]);
    62             }
    63         }
    64         rep (len, 1, n) {
    65             idxK[len] = 0;
    66             while((1 << (idxK[len] + 1)) <= len) idxK[len] ++;
    67         }
    68     }
    69     int rmq_min(int l, int r) {
    70         int len = r - l + 1, k = idxK[len];
    71         return min(mi[l][k], mi[r - (1 << k) + 1][k]);
    72     }
    73     void lcp_init() {
    74         get_height();
    75         rmq_init(height, n);
    76     }
    77     int get_lcp(int a, int b) {
    78         if(a == b) return n - a - 1;
    79         return rmq_min(min(rnk[a], rnk[b]) + 1, max(rnk[a], rnk[b]));
    80     }
    81     void solve() {
    82     }
    83 };
  • 相关阅读:
    最近学习的 Node.js 之 http
    最近学习的 Node.js 基础:安装、环境配置、forever
    关于MySQL5.7 几天的总结(简单分区 & json类型)
    不会点git真不行啊.
    python爬虫基础_scrapy
    python爬虫基础_webwechat
    python爬虫基础_requests和bs4
    python之django母板页面
    python之django基础
    python网络之web框架
  • 原文地址:https://www.cnblogs.com/gj-Acit/p/4527641.html
Copyright © 2011-2022 走看看