SDOI2008 Sandy的卡片( 后缀数组 )
2016-01-16 20:42
375 查看
求出后缀数组, 然后二分答案, 对height数组分组检验答案. 时间复杂度O(|S| log|S|)
--------------------------------------------------------------------------------
#include<cstdio>#include<cctype>#include<cstring>#include<algorithm> using namespace std; const int maxn = 1009;const int maxN = 1000009; inline int read() { char c = getchar(); for(; !isdigit(c); c = getchar()); int ret = 0; for(; isdigit(c); c = getchar()) ret = ret * 10 + c - '0'; return ret;} bool vis[maxn];int str[maxn][maxn], len[maxn], n, Top;int S[maxN], Id[maxN], stk[maxN], N;int cnt[maxN], Sa[maxN], Height[maxN], Rank[maxN]; void Build(int m) { int *x = Height, *y = Rank; for(int i = 0; i < m; i++) cnt[i] = 0; for(int i = 0; i < N; i++) cnt[x[i] = S[i]]++; for(int i = 1; i < m; i++) cnt[i] += cnt[i - 1]; for(int i = N; i--; ) Sa[--cnt[x[i]]] = i; for(int k = 1, p = 0; k <= N; k <<= 1, p = 0) { for(int i = N - k; i < N; i++) y[p++] = i; for(int i = 0; i < N; i++) if(Sa[i] >= k) y[p++] = Sa[i] - k; for(int i = 0; i < m; i++) cnt[i] = 0; for(int i = 0; i < N; i++) cnt[x[y[i]]]++; for(int i = 1; i < m; i++) cnt[i] += cnt[i - 1]; for(int i = N; i--; ) Sa[--cnt[x[y[i]]]] = y[i]; swap(x, y); p = 1; x[Sa[0]] = 0; for(int i = 1; i < N; i++) { if(y[Sa[i]] != y[Sa[i - 1]] || y[Sa[i] + k] != y[Sa[i - 1] + k]) p++; x[Sa[i]] = p - 1; } if(p >= N) break; m = p; } for(int i = 0; i < N; i++) Rank[Sa[i]] = i; Height[0] = 0; for(int i = 0, h = 0; i < N; i++) if(Rank[i]) { if(h) h--; while(S[i + h] == S[Sa[Rank[i] - 1] + h]) h++; Height[Rank[i]] = h; }} void Init() { int mn = 1 << 30, mx = -1 << 30; n = read(); for(int i = 0; i < n; i++) { len[i] = read(); for(int j = 0; j < len[i]; j++) str[i][j] = read(); for(int j = len[i]; --j; ) { str[i][j] -= str[i][j - 1]; mn = min(mn, str[i][j]); mx = max(mx, str[i][j]); } } N = 0; for(int i = 0; i < n; i++) { for(int j = 1; j < len[i]; j++) { S
= str[i][j] - mn + n; Id[N++] = i; } S
= n - i - 1; Id[N++] = n; } Build(mx - mn + n + 1); memset(vis, 0, sizeof vis); vis
= 1; Top = 0;} bool chk(int v) { while(Top) vis[stk[--Top]] = 0; for(int i = 1; i < N; i++) if(Height[i] >= v) { if(!vis[Id[Sa[i - 1]]]) vis[stk[Top++] = Id[Sa[i - 1]]] = 1; if(!vis[Id[Sa[i]]]) vis[stk[Top++] = Id[Sa[i]]] = 1; if(Top >= n) return true; } else { while(Top) vis[stk[--Top]] = 0; } return false;} void Work() { int l = 1, r = maxN, ans = 0; while(l <= r) { int m = (l + r) >> 1; if(chk(m)) { ans = m, l = m + 1; } else r = m - 1; } printf("%d\n", ++ans);} int main() { Init(); Work(); return 0;}--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
#include<cstdio>#include<cctype>#include<cstring>#include<algorithm> using namespace std; const int maxn = 1009;const int maxN = 1000009; inline int read() { char c = getchar(); for(; !isdigit(c); c = getchar()); int ret = 0; for(; isdigit(c); c = getchar()) ret = ret * 10 + c - '0'; return ret;} bool vis[maxn];int str[maxn][maxn], len[maxn], n, Top;int S[maxN], Id[maxN], stk[maxN], N;int cnt[maxN], Sa[maxN], Height[maxN], Rank[maxN]; void Build(int m) { int *x = Height, *y = Rank; for(int i = 0; i < m; i++) cnt[i] = 0; for(int i = 0; i < N; i++) cnt[x[i] = S[i]]++; for(int i = 1; i < m; i++) cnt[i] += cnt[i - 1]; for(int i = N; i--; ) Sa[--cnt[x[i]]] = i; for(int k = 1, p = 0; k <= N; k <<= 1, p = 0) { for(int i = N - k; i < N; i++) y[p++] = i; for(int i = 0; i < N; i++) if(Sa[i] >= k) y[p++] = Sa[i] - k; for(int i = 0; i < m; i++) cnt[i] = 0; for(int i = 0; i < N; i++) cnt[x[y[i]]]++; for(int i = 1; i < m; i++) cnt[i] += cnt[i - 1]; for(int i = N; i--; ) Sa[--cnt[x[y[i]]]] = y[i]; swap(x, y); p = 1; x[Sa[0]] = 0; for(int i = 1; i < N; i++) { if(y[Sa[i]] != y[Sa[i - 1]] || y[Sa[i] + k] != y[Sa[i - 1] + k]) p++; x[Sa[i]] = p - 1; } if(p >= N) break; m = p; } for(int i = 0; i < N; i++) Rank[Sa[i]] = i; Height[0] = 0; for(int i = 0, h = 0; i < N; i++) if(Rank[i]) { if(h) h--; while(S[i + h] == S[Sa[Rank[i] - 1] + h]) h++; Height[Rank[i]] = h; }} void Init() { int mn = 1 << 30, mx = -1 << 30; n = read(); for(int i = 0; i < n; i++) { len[i] = read(); for(int j = 0; j < len[i]; j++) str[i][j] = read(); for(int j = len[i]; --j; ) { str[i][j] -= str[i][j - 1]; mn = min(mn, str[i][j]); mx = max(mx, str[i][j]); } } N = 0; for(int i = 0; i < n; i++) { for(int j = 1; j < len[i]; j++) { S
= str[i][j] - mn + n; Id[N++] = i; } S
= n - i - 1; Id[N++] = n; } Build(mx - mn + n + 1); memset(vis, 0, sizeof vis); vis
= 1; Top = 0;} bool chk(int v) { while(Top) vis[stk[--Top]] = 0; for(int i = 1; i < N; i++) if(Height[i] >= v) { if(!vis[Id[Sa[i - 1]]]) vis[stk[Top++] = Id[Sa[i - 1]]] = 1; if(!vis[Id[Sa[i]]]) vis[stk[Top++] = Id[Sa[i]]] = 1; if(Top >= n) return true; } else { while(Top) vis[stk[--Top]] = 0; } return false;} void Work() { int l = 1, r = maxN, ans = 0; while(l <= r) { int m = (l + r) >> 1; if(chk(m)) { ans = m, l = m + 1; } else r = m - 1; } printf("%d\n", ++ans);} int main() { Init(); Work(); return 0;}--------------------------------------------------------------------------------
相关文章推荐
- storm安装部署
- 基于八叉树的区域增长点云分割算法
- Latest CLM fixes for 2015
- 【天蝎WG-概念篇】数据仓库之星型结构
- windows 批处理自学教程 基础篇
- 从最大似然到EM算法浅解
- Hive的安装以及基本的shell操作以及基本模型的介绍
- 多彩的霓虹灯
- 【转】国内较快的maven镜像
- linux学习笔记----文件与目录管理
- OJ 系列之整型字符串排序
- httpd-2.4.18源码安装
- Spring框架概况(一)
- Android使用LruCache,DiskLruCache结合线程池打造类似(ImageLoader)图片加载器
- POJ 1007 Java:DNA Sorting
- 丹东市国土资源信息中心派专业技术人员外出学习培训心得
- 互联网企业需要加强道德自律
- Loaded:loaded(/usr/lib/systemd/system/iptables.service;enabled)Active: inactive
- 调整数组顺序使奇数位于偶数之前
- 答题游戏项目2