spoj 7258 Lexicographical Substring Search(后缀数组 | 后缀自动机)
来源:互联网 发布:格罗玛什地狱咆哮知乎 编辑:程序博客网 时间:2024/05/22 03:14
题目链接:spoj 7258 Lexicographical Substring Search
代码 - 后缀数组
#include <cstdio>#include <cstring>#include <stack>#include <vector>#include <algorithm>using namespace std;const int maxn = 90000 + 5;struct Suffix_Arr { int n, s[maxn]; int SA[maxn], rank[maxn], height[maxn]; int tmp_one[maxn], tmp_two[maxn], c[305]; void init(char* str); void build(int m); void get_height(); int f[maxn]; void solve(); void query(char* str, int k);}SFA;char str[maxn];int main () { scanf("%s", str); SFA.init(str); int q, k; SFA.solve(); scanf("%d", &q); while (q--) { scanf("%d", &k); SFA.query(str, k); } return 0;}void Suffix_Arr::init(char* str) { n = 0; int len = strlen(str); for (int i = 0; i < len; i++) s[n++] = str[i]; s[n++] = 0;}void Suffix_Arr::query(char* str, int k) { int idx = lower_bound(f, f + n, k) - f; int bw = k - f[idx-1] + height[idx], s = SA[idx]; for (int i = 0; i < bw; i++) printf("%c", str[s+i]); printf("\n");}void Suffix_Arr::solve() { build(300); get_height(); f[0] = 0; for (int i = 1; i < n; i++) f[i] = f[i-1] + (n - 1 - SA[i] - height[i]);}void Suffix_Arr::get_height() { for (int i = 0; i < n; i++) rank[SA[i]] = i; int mv = height[0] = 0; for (int i = 0; i < n - 1; i++) { if (mv) mv--; int j = SA[rank[i]-1]; while (s[i+mv] == s[j+mv]) mv++; height[rank[i]] = mv; }}void Suffix_Arr::build(int m) { int* x = tmp_one, *y = tmp_two; 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 mv = 0; for (int i = n - k; i < n; i++) y[mv++] = i; for (int i = 0; i < n; i++) if(SA[i] >= k) y[mv++] = 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); mv = 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] ? mv - 1 : mv++); if (mv >= n) break; m = mv; }}
代码-后缀自动机
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;typedef long long ll;const int maxn = 90005; const int SIGMA_SIZE = 26;struct SAM { int sz, last; int g[maxn<<1][SIGMA_SIZE], pre[maxn<<1], step[maxn<<1]; int pos[maxn<<1], right[maxn<<1]; ll cnt[maxn<<1]; void newNode(int s) { step[++sz] = s; pre[sz] = 0; memset(g[sz], 0, sizeof(g[sz])); } int idx(char ch) { return ch -'a'; } void init() { sz = 0, last = 1; newNode(0); } void insert(char ch); void get_tuopu(); void get_right(char* str); void presolve() { get_tuopu(); for (int i = 1; i <= sz; i++) cnt[i] = 1; for (int i = sz; i; i--) { int u = pos[i]; for (int j = 0; j < SIGMA_SIZE; j++) cnt[u] += cnt[g[u][j]]; } } void query(int k) { int p = 1; while (k) { k--; for (int i = 0; i < SIGMA_SIZE; i++) { int u = g[p][i]; if (u == 0) continue; if (cnt[u] <= k) k -= cnt[u]; else { printf("%c", i + 'a'); p = u; break; } } } printf("\n"); /* for (int i = 1; i <= sz; i++) printf("%d %lld\n", i, cnt[i]); */ }}SA;char str[maxn];int main () { scanf("%s", str); int n = strlen(str), k; SA.init(); for (int i = 0; i < n; i++) SA.insert(str[i]); SA.presolve(); scanf("%d", &n); while (n--) { scanf("%d", &k); SA.query(k); } return 0;}void SAM::insert(char ch) { newNode(step[last] + 1); int v = idx(ch), p = last, np = sz; while (p && !g[p][v]) { g[p][v] = np; p = pre[p]; } if (p) { int q = g[p][v]; if (step[q] == step[p] + 1) pre[np] = q; else { newNode(step[p] + 1); int nq = sz; for (int j = 0; j < SIGMA_SIZE; j++) g[nq][j] = g[q][j]; pre[nq] = pre[q]; pre[np] = pre[q] = nq; while (p && g[p][v] == q) { g[p][v] = nq; p = pre[p]; } } } else pre[np] = 1; last = np;}void SAM::get_tuopu() { for (int i = 0; i <= sz; i++) cnt[i] = 0; for (int i = 1; i <= sz; i++) cnt[step[i]]++; for (int i = 1; i <= sz; i++) cnt[i] += cnt[i-1]; for (int i = 1; i <= sz; i++) pos[cnt[step[i]]--] = i; }void SAM::get_right(char* str) { int p = 1, n = strlen(str); for (int i = 0; i <= sz; i++) right[i] = 0; for (int i = 0; i < n; i++) { int v = idx(str[i]); p = g[p][v]; right[p]++; } for (int i = sz; i; i--) { int u = pos[i]; right[pre[u]] += right[u]; }}
0 0
- spoj 7258 Lexicographical Substring Search(后缀数组 | 后缀自动机)
- spoj 7258 Lexicographical Substring Search (后缀自动机)
- SPOJ 7258 SUBLEX - Lexicographical Substring Search (后缀自动机)
- SPOJ Lexicographical Substring Search --后缀自动机
- SPOJ SUBLEX Lexicographical Substring Search 后缀自动机
- 【后缀自动机】[SPOJ SUBLEX]Lexicographical Substring Search
- SPOJ Lexicographical Substring Search 后缀自动机
- spoj 7258 Lexicographical Substring Search (后缀自动机+dp)
- SPOJ 题目7528 SUBLEX - Lexicographical Substring Search(后缀自动机求排名k的子串)
- spoj7258 Lexicographical Substring Search(SUBLEX) 后缀自动机
- [spoj7258]Lexicographical Substring Search && 后缀自动机
- spoj7258:Lexicographical Substring Search 后缀自动机
- 【SPOJ7258】Lexicographical Substring Search-后缀自动机+拓补序递推
- spoj7258 Lexicographical Substring Search(SUBLEX),后缀自动机
- [SPOJ7258]SUBLEX - Lexicographical Substring Search(后缀自动机)
- spoj7258:Lexicographical Substring Search(后缀自动机+拓扑排序)
- spoj 694,705 后缀数组,后缀自动机
- SPOJ 1811 Longest Common Substring(后缀自动机)
- UML中关联(Association)、聚合(Aggregation)和合成(Composition)之间的区别
- linux新定时器:timefd及相关操作函数
- 正则表达式
- Linux task_struct parent 和 real_parent 的区别
- FreeMarker-3
- spoj 7258 Lexicographical Substring Search(后缀数组 | 后缀自动机)
- kettle连接hive错误
- Android 在Activity中关闭Activity
- 【11/09】 iOS开发成长之路,【iOS真机测试出现iPhone unavailable】Xcode7 真机测试,真机出现"unavailable"字样,Could not find develo
- 同步异步堵塞非堵塞
- Deprecated: Function xxx() is deprecated
- 一个maven项目打多个可执行Jar文件
- UIView,UIButton,UIImageView等设置圆角,设置阴影,设置边框的方法
- Android APP应用开发中异常处理