博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Milk Patterns POJ - 3261
阅读量:4558 次
发布时间:2019-06-08

本文共 3278 字,大约阅读时间需要 10 分钟。

Milk Patterns

 

第一道后缀数组,,有点蒙逼=_=



update:  2018-01-27

题意:求至少出现k次的最长子串的长度。

可以二分长度mid,看是否能出现k次。

如何判断出现k次?

由后缀数组的height数组, 将height数组按顺序分组,每一组内的最长公共前缀不小于mid(小于mid的自成一组),统计最大组的height个数即可。

 

1 #include 
2 #include
3 #include
4 #include
5 using namespace std; 6 #define FP freopen("in.txt","r".stdin); 7 8 const int maxn=20010; 9 int s[maxn], s1[maxn];10 int sa[maxn], t[maxn], t2[maxn], c[maxn], n, k;11 int rank[maxn], height[maxn];12 13 void build_sa(int m, int n){14 int i, *x=t, *y=t2;15 //基数排序16 for(i = 0; i < m; i++) c[i] = 0;17 for(i = 0; i < n; i++) c[x[i] = s[i]]++;18 for(i = 1; i < m; i++) c[i] += c[i-1];19 for(i = n-1;i >= 0; i--) sa[--c[x[i]]] = i;20 21 for(int k = 1; k <= n; k <<= 1){22 int p=0;23 //直接利用sa数组排序第二关键字24 for(i = n-k; i < n; i++) y[p++] = i;25 for(i = 0; i < n; i++) if(sa[i] >= k) y[p++] = sa[i] - k;26 27 //基数排序第一关键字28 for(i = 0; i < m; i++) c[i] = 0;29 for(i = 0; i < n; i++) c[x[y[i]]]++;30 for(i = 1; i < m; i++) c[i] += c[i-1];31 for(i = n-1; i >= 0; i--) sa[--c[x[y[i]]]] = y[i];32 //根据sa和y数组计算新的x数组33 swap(x, y);34 p = 1;35 x[sa[0]] = 0;36 for(i = 1; i < n; i++) 37 x[sa[i]] = y[sa[i-1]]==y[sa[i]] && y[sa[i-1]+k]==y[sa[i]+k] ? p-1 : p++;38 39 if(p >= n) break; //以后即使继续倍增,sa也不会改变,推出40 m = p; //下次基数排序的最大值41 }42 }43 44 void getHeight(int n) {45 int i, j, k = 0;46 for(i = 0; i <= n; i++) rank[sa[i]] = i;47 for(i = 0; i < n; i++) {48 if(k) k--;49 j = sa[rank[i]-1];50 while(s[i+k] == s[j+k]) k++;51 height[rank[i]] = k;52 }53 }54 int m; //模板长度55 56 int main(){57 while(scanf("%d%d", &n, &k)!=EOF){58 for(int i = 0; i < n; i++) scanf("%d",&s[i]);59 for(int i = 0; i < n; i++) s1[i] = s[i];60 sort(s, s+n);61 int sz=unique(s,s+n)-s;62 for(int i = 0; i < n; i++) {63 s1[i]=lower_bound(s,s+sz,s1[i])-s+1;64 }65 for(int i = 0; i <= n; i++) s[i]=s1[i];66 build_sa(256, n+1);67 getHeight(n);68 int l=1, r=n;69 while(l <= r) { 70 int cnt=1;71 int m=(l+r)>>1;72 for(int i = 1; i <= n; i++){73 if(height[i] >= m) cnt++;74 else cnt=1;75 if(cnt>=k) break;76 }77 if(cnt >= k) l=m+1;78 else r=m-1;79 }80 printf("%d\n", r);81 }82 83 }
View Code

 

 

也可用哈希做,慢

1 #include 
2 #include
3 #include
4 #include
5 using namespace std; 6 #define ull unsigned long long 7 const int maxn=20010; 8 const int seed=131; 9 10 ull base[maxn],h[maxn];11 int a[maxn];12 int n,k;13 14 int check(int m)15 {16 memset(h,0,sizeof(h));17 for(int i=0;i
=m;i--){24 if(h[i]==h[i-1]) cnt++;25 else cnt=1;26 if(cnt>=k) return 1;27 }28 return 0;29 }30 int main()31 {32 base[0]=1;33 for(int i=1;i
View Code

 

转载于:https://www.cnblogs.com/yijiull/p/7518093.html

你可能感兴趣的文章
.NET Core WebAPI IIS 部署问题
查看>>
SystemTap 静态探针安装包
查看>>
redis五种数据类型的使用
查看>>
Form表单中的onClick,onSubmit和submit
查看>>
Python-SocketServer源码
查看>>
JavaScript-基本数据类型
查看>>
CentOS 7.3 实体机启动 U 盘制作
查看>>
mysql数据库
查看>>
dede调用文章里的图片
查看>>
windows 窗体基本控件
查看>>
unix date 命令获取某日期的前一天
查看>>
python中set、list、dict内部实现原理
查看>>
Python3 MySQL 数据库连接
查看>>
正则\1\2和\\1的理解
查看>>
Python文件操作(一)
查看>>
Sage CRM 平衡区域树结构
查看>>
Codeforces Round #228 (Div. 1) C. Fox and Card Game 博弈
查看>>
APUE读书笔记-第16章-网络IPC: 套接字
查看>>
babel更新之后的 一些坑
查看>>
Python基础-Alex
查看>>