[BZOJ 1396] 识别子串
2016-05-14 21:07
253 查看
http://www.lydsy.com/JudgeOnline/problem.php?id=1396
Solution:
我得了“能用后缀数组就一定不用后缀自动机综合症”….感觉用height、rank、sa 处理字符串真的好优雅….
虽然其他题上后缀数组常数比较大…不过这个后缀数组水了一发似乎就Rank1 了…开心
题解就是求出后缀数组以后维护一个单调队列来更新答案啦。。。
Solution:
我得了“能用后缀数组就一定不用后缀自动机综合症”….感觉用height、rank、sa 处理字符串真的好优雅….
虽然其他题上后缀数组常数比较大…不过这个后缀数组水了一发似乎就Rank1 了…开心
题解就是求出后缀数组以后维护一个单调队列来更新答案啦。。。
#include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> #define rep(i, x, y) for (int i = (x), _ = (y); i <= _; ++i) #define down(i, x, y) for (int i = (x), _ = (y); i >= _; --i) #define x first #define y second #define LX_JUDGE using namespace std; typedef long long LL; template<typename T> inline void up_max(T & x, T y) { x < y ? x = y : 0; } template<typename T> inline void up_min(T & x, T y) { x > y ? x = y : 0; } template<typename T> inline void read(T & x) { char c; while ((c = getchar()) < '0' || c > '9') ; for (x = c - '0'; (c = getchar()) >= '0' && c <= '9'; x = x * 10 + c - '0') ; } const int inf = 0x3f3f3f3f ; const int N = 1e5 + 10; namespace Suffix_Array { int Sa , Rank , height ; void Suffix_Da(char * r, int n, int m) { static int ws ; int i, j, p, *x = Rank, *y = height; memset(ws, 0, sizeof(int) * m); 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; --i) Sa[--ws[x[i]]] = i; for (j = p = 1; p < n; j <<= 1, 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; memset(ws, 0, sizeof(int) * m); for (i = 0; i < n; ++i) ++ws[x[i]]; for (i = 1; i < m; ++i) ws[i] += ws[i - 1]; for (i = n - 1; ~i; --i) Sa[--ws[x[y[i]]]] = y[i]; swap(x, y); x[Sa[0]] = 0, p = 1; for (i = 1; i < n; ++i) x[Sa[i]] = (y[Sa[i - 1]] == y[Sa[i]] && y[Sa[i - 1] + j] == y[Sa[i] + j]) ? p - 1 : p++; } for (i = 0; i < n; ++i) Rank[Sa[i]] = i; for (p = 0, i = 0; i < n - 1; ++i) { p ? --p : 0; j = Sa[Rank[i] - 1]; while (r[i + p] == r[j + p]) ++p; height[Rank[i]] = p; } height = height[0] = height[1] = 0; } } namespace My_Worker { typedef pair<int , int> Data; Data que ; int left = 1, right = 0; void insert(Data u) { while (left <= right && u.y - u.x <= que[right].y - que[right].x) --right; que[++right] = u; } int query(int x) { #define calc(o) (max((o).y, x) - (o).x + 1) while (left < right && calc(que[left + 1]) <= calc(que[left])) ++left; return calc(que[left]); #undef calc } } char str ; int main() { #ifdef LX_JUDGE freopen("in.txt", "r", stdin); #endif using namespace Suffix_Array; using namespace My_Worker; scanf("%s", str); int n = strlen(str); str[n++] = 0; Suffix_Da(str, n, 128); rep (i, 0, n - 2) { int tmp = i + max(height[Rank[i]], height[Rank[i] + 1]); if (tmp < n - 1) insert(Data(i, tmp)); printf("%d\n", query(i)); } return 0; }
相关文章推荐
- js笔记之影音插入0514
- jQuery选择器总结
- SQL的存储过程的理解与应用(以mysql为例)
- WEB架构师成长之路-摘录
- windows assembler helloworld
- java hdu2012素数判定
- jboss-as- 7.1.1.Final配置jndi数据源
- 指针篇
- faster_rcnn c++版本的 caffe 封装,动态库(2)
- debian完整部署 Nginx + uWSGI + Django
- android /data文件夹无法显示内容
- c++中string类成员函数的总结
- Android执行文件apk的组成结构
- php 数字转换大写汉字
- 【Stanford机器学习笔记】11-Unsupervised Learning
- tomcat中如何运行war包呢
- leetcode wiggle-sort-ii(未完成)
- js将日期转换为毫秒值
- windows系统中国国内镜像网站上用repo下载Android5.0源码
- 关于安卓图库更新的问题终极解决方法(实测)