【SuffixArray】bzoj1717 [Usaco2006 Dec] Milk Patterns 产奶的模式
2015-08-10 20:37
429 查看
传送门:BZOJ1717
然后么。。为什么我写的这么长?!
是罗穗骞的论文题嘛……就当给后缀数组练手吧
可重叠k次重复字串
真的不想…一直做码题~~
解题思路
先把正解说一说:单调队列或者二分然后么。。为什么我写的这么长?!
是罗穗骞的论文题嘛……就当给后缀数组练手吧
可重叠k次重复字串
YM代码
#include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for(int i = (a); i <= (b); i++) #define red(i, a, b) for(int i = (a); i >= (b); i--) #define ll long long inline int read() { int x = 0; char ch = getchar(); while(ch < '0' || ch > '9') ch = getchar(); while(ch >= '0' || ch <= '9') { x *= 10; x += ch - '0'; ch = getchar(); } return x; } const int N = 20005; int n, m, k, p, q, tot = 0; int a , num , hash , v , h , height , sa[2] , rank[2] ; int find(int x) { int l = 1, r = tot, ans = 0; while(l <= r) { int mid = (l + r) >> 1; if (hash[mid] <= x) ans = mid, l = mid + 1; else r = mid - 1; } return ans; } bool jud(int x) { int tmp = 0; rep(i, 1, n) { if (height[i] >= x) { tmp++; if (tmp == m-1) return 1; }else tmp = 0; } return 0; } void getans() { k = 0; rep(i, 1, n) { if (rank[p][i] == 1) h[i] = 0; else { int j = sa[p][rank[p][i]-1]; while(a[i+k] == a[j+k]) k++; h[i] = k; if (k > 0) k--; } } rep(i, 1, n) height[rank[p][i]] = h[i]; int l = 1, r = n, ans = 0; while(l <= r) { int mid = (l + r) >> 1; if (jud(mid)) ans = mid, l = mid + 1; else r = mid - 1; } printf("%d\n", ans); } void calsa(int sa , int rk , int SA , int RK ) { rep(i, 1, n) v[rk[sa[i]]] = i; red(i, n, 1) if (sa[i] > k) SA[v[rk[sa[i]-k]]--] = sa[i] - k; rep(i, n-k+1, n) SA[v[rk[i]]--] = i; rep(i, 1, n) RK[SA[i]] = RK[SA[i-1]] + (rk[SA[i]] != rk[SA[i-1]] || rk[SA[i]+k] != rk[SA[i-1]+k]); } void work() { p = 0, q = 1; a[0] = -1; rep(i, 1, n) v[a[i]]++; rep(i, 1, n) v[i] += v[i-1]; rep(i, 1, n) sa[p][v[a[i]]--] = i; rep(i, 1, n) if(a[sa[p][i]] != a[sa[p][i-1]]) rank[p][sa[p][i]] = rank[p][sa[p][i-1]] + 1; else rank[p][sa[p][i]] = rank[p][sa[p][i-1]]; k = 1; while(k < n) { calsa(sa[p], rank[p], sa[q], rank[q]); p^=1; q^=1; k<<=1; } getans(); } int main() { scanf("%d%d", &n, &m); rep(i, 1, n) { scanf("%d", &a[i]); num[i] = a[i]; } sort(num + 1, num + n + 1); hash[++tot] = num[1]; rep(i, 2, n) { if (num[i] != num[i-1]) hash[++tot] = num[i]; } rep(i, 1, n) a[i] = find(a[i]); work(); return 0; }
尾声
好长好长…好长好长…真的不想…一直做码题~~
End.
相关文章推荐
- JSON for C++ 介绍1
- 真正认识 JFrame 和 getContentPane() 方法
- wget www.baidu.com执行流程分析
- HDU 5167 Fibonacci——BestCoder Round #28(搜索+预处理)
- cocos2d-x手机游戏(IOS版本)接入分享shareSDK(新浪微博和微信分享)记录
- C语言-FunctionPointer
- 二分图匹配学习——匈牙利算法模板
- BZOJ1007
- hdu 5365+hdu 5355
- hdu 2029 Palindromes _easy version(回文串)
- HttpSessionListener接口监听网站在线人数
- SeekBar拖动条的使用
- (二)表的连接与外键约束
- VS2010 添加静态链接库(包括.h文件和.lib文件)以添加jsoncpp为例
- 【COCI 2012】Germ
- 从头到尾彻底解析Hash表算法
- 【MySql】使用记录<三>
- poj3667hotal线段树【经典】
- (二)表的连接与外键约束
- SQL语言