poj 3693 Maximum repetition substring(后缀数组)
来源:互联网 发布:php ob_end_clean 编辑:程序博客网 时间:2024/04/30 23:23
题目链接:poj 3693 Maximum repetition substring
题目大意:求一个字符串中循环子串次数最多的子串。
解题思路:对字符串构建后缀数组,然后枚举循环长度,分区间确定。对于一个长度l,每次求出i和i+l的LCP,那么以i为起点,循环子串长度为l的子串的循环次数为LCP/l+1,然后再考虑一下从i-l+1~i之间有没有存在增长的可能性。
#include <cstdio>#include <cstring>#include <vector>#include <algorithm>using namespace std;const int maxn = 100005;struct Suffix_Arr { int n, s[maxn]; int SA[maxn], rank[maxn], height[maxn]; int tmp_one[maxn], tmp_two[maxn], c[305]; int d[maxn][20]; void init(char* str); void build(int m); void get_height(); void rmq_init(); int rmq_query(int x, int y); void solve();}AC;char str[maxn];int main () { int cas = 0; while (scanf("%s", str) == 1 && strcmp(str, "#")) { AC.init(str); AC.build(27); AC.get_height(); printf("Case %d: ", ++cas); AC.solve(); } 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] - 'a' + 1; s[n++] = 0;}void Suffix_Arr::solve() { /* for (int i = 0; i < n; i++) printf("%d ", SA[i]); printf("\n"); for (int i = 0; i < n; i++) printf("%d ", height[i]); printf("\n"); */ rmq_init(); int ans = 0; vector<int> vec; for (int l = 1; l < n; l++) { for (int i = 0; i + l < n; i += l) { int lcp = rmq_query(rank[i], rank[i + l]); int k = lcp / l + 1; int p = i - (l - lcp % l); if (p >= 0 && lcp % l && rmq_query(rank[p], rank[p + l]) >= lcp) k++; if (k > ans) { ans = k; vec.clear(); } if (k == ans) vec.push_back(l); } } int pos, len; for (int i = 0; i < n; i++) { bool flag = false; for (int j = 0; j < vec.size(); j++) { if (SA[i] + vec[j] >= n) continue; if (rmq_query(i, rank[SA[i] + vec[j]]) >= (ans - 1) * vec[j]) { pos = SA[i]; len = vec[j] * ans; flag = true; break; } } if (flag) break; } for (int i = 0; i < len; i++) printf("%c", s[pos + i] + 'a' - 1); printf("\n");}void Suffix_Arr::rmq_init() { for (int i = 0; i < n; i++) d[i][0] = height[i]; for (int k = 1; (1<<k) <= n; k++) { for (int i = 0; i + (1<<k) - 1 < n; i++) d[i][k] = min(d[i][k-1], d[i+(1<<(k-1))][k-1]); }}int Suffix_Arr::rmq_query(int x, int y) { if (x == y) return d[x][0]; if (x > y) swap(x, y); x++; int k = 0; while ((1<<(k+1) <= y - x + 1)) k++; return min(d[x][k], d[y - (1<<k) + 1][k]);}void Suffix_Arr::get_height() { for (int i = 0; i < n; i++) rank[SA[i]] = i; int mv = height[n-1] = 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; }}
1 0
- poj 3693 Maximum repetition substring //后缀数组
- poj 3693 Maximum repetition substring (后缀数组)
- poj 3693 Maximum repetition substring(后缀数组)
- poj 3693 Maximum repetition substring(后缀数组)
- 【后缀数组】【poj 3693】Maximum repetition substring
- POJ 3693 Maximum Repetition Substring 后缀数组
- poj 3693 Maximum repetition substring(后缀数组好题)
- POJ 3693 Maximum repetition substring(RMQ+后缀数组)
- POJ 3693 Maximum repetition substring (后缀数组)
- 【后缀数组】 HDOJ 2459 && POJ 3693 Maximum repetition substring
- poj 3693 Maximum repetition substring(有点麻烦的后缀数组)
- POJ 3693 Maximum repetition substring(后缀数组神题)
- [后缀数组+枚举] hdu 2459 && poj 3693 Maximum repetition substring
- poj 3693 Maximum repetition substring 后缀数组+RMQ
- POJ 3693 - Maximum repetition substring (后缀数组)
- POJ 3693 Maximum repetition substring 后缀数组 暴力 rmq
- POJ 3693 Maximum repetition substring(后缀数组)
- POJ 3693 Maximum repetition substring 后缀数组 + RMQ预处理
- 如何优化Mysql千万级快速分页,limit优化快速分页,MySQL处理千万级数据查询的优化方案!
- UNISON - ZOJ 2685 dp
- 将datatable数据转化成list
- [2000]Gold Coins(水题)POJ
- 安卓图片--Bitmap与Drawable与byte[]与InputStream之间的转换工具类【转】
- poj 3693 Maximum repetition substring(后缀数组)
- MYSQL入门学习之三十:MySQL锁定机制简介
- hdu1878(判断有无欧拉回路)
- 关于Arcgis数据导入mdb完成后如何立刻解除mdb的锁定
- 【索引】String Algorithms::Examples
- 个人专著《企业级GIS设计管理优化策略》已经出版等待您的选购
- 基于Storm的Nginx log实时监控系统
- .net 验证码
- hdu1558——Segment set