(模板)后缀数组(lcp和rmq)
2014-10-13 23:09
603 查看
char s[mxn]; int sa[mxn], t[mxn], t2[mxn], c[mxn], f[mxn][20], ft[mxn]; int Rank[mxn], height[mxn]; void get_sa(int m, int n) { //n = strlen(s) + 1; int i, *x = t, *y = t2; for(i = 0; i < m; ++i) c[i] = 0; for(i = 0; i < n; ++i) ++c[x[i]=s[i]]; for(i = 1; i < m; ++i) c[i] += c[i-1]; for(i = n - 1; i >= 0; --i) sa[--c[x[i]]] = i; for(int k = 1; k <= n; k <<= 1) { int p = 0; for(i = n - k; i < n; ++i) y[p++] = i; for(i = 0; i < n; ++i) if(sa[i] >= k) y[p++] = sa[i] - k; for(i = 0; i < m; ++i) c[i] = 0; for(i = 0; i < n; ++i) c[x[y[i]]] ++; for(i = 1; i < m; ++i) c[i] += c[i-1]; for(i = n - 1; i >= 0; --i) sa[--c[x[y[i]]]] = y[i]; swap(x, y); p = 1, x[sa[0]] = 0; for(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; } } void get_h(int n) { int i, j, k = 0; for(i = 1; i <= n; ++i) Rank[sa[i]] = i; for(i = 0; i < n; ++i) { if(k) --k; j = sa[Rank[i]-1]; while(s[i+k] == s[j+k]) ++k; height[Rank[i]] = k; } } void rmq(int n) { for(int i = 0; i < mxn; ++i) ft[i] = (int)(log(i * 1.0) / log(2.0)); for(int i = 1; i <= n; ++i) f[i][0] = height[i]; for(int j = 1; j < 20; ++j) for(int i =1; i + (1 << j) - 1 <= n; ++i) f[i][j] = min(f[i][j-1], f[i+(1<<j-1)][j-1]); } int lcp(int a, int b) { int x = Rank[a], y = Rank[b]; if(x > y) swap(x, y); ++x; int t = ft[y-x+1]; return min(f[x][t], f[y-(1<<t)+1][t]); }
相关文章推荐
- 后缀数组模板/LCP模板
- uval1297 Palindrome 后缀数组求最长回文字串,lcp,rmq
- hdu 4691 最长的共同前缀 后缀数组 +lcp+rmq
- hdu 4691 最长公共前缀 后缀数组 +lcp+rmq
- hdu5008 Boring String Problem,2014西安网络赛B题,后缀数组,RMQ
- URAL1297Palindrome(最长回文子串 、后缀数组最长公共前缀+RMQ)
- POJ 1743 Musical Theme (二分后缀数组LCP)
- 后缀数组 模板
- poj 2774 Long Long Message 后缀数组模板
- RMQ模板 求区间最大、最小值。 (前提是数组一旦确定便不再频繁更改)
- 【后缀数组模板】
- HDU 6194 string string string 后缀数组 + RMQ(线段树)
- POJ 1743 - Musical Theme 后缀数组模板+用后缀数组求不覆盖最长重复子序列
- 【tyvj 1860】 后缀数组模板
- 【UOJ #35】后缀排序 后缀数组模板
- 后缀数组模板-boj477.新来的小妹妹 & boj477. 田田背课文
- 最长公共子串(后缀数组+LCP)
- hdu6194 string string string 后缀数组 + RMQ
- 后缀数组模板整理
- 后缀数组模板