HDU 4080 Stammering Aliens && 后缀数组
来源:互联网 发布:域名指向ip端口 编辑:程序博客网 时间:2024/06/05 11:30
题意:给你数字m和一个字符串,问你在字符串中至少出现m次的子串的最大长度,并输出子串最后出现的首字母的位置,如果长度相同时有多种情况取最后一次最靠后出现的那个。(没考虑这个,WA了好几天。我是弱渣渣~)
解法:先求出后缀数组,然后二分长度,判断这个长度是否出现过m次,如果出现了m次 ,先判断长度是否是最大,再判断最后一个是否足够靠后。
代码:
#include<iostream>#include<cstdio>#include<string>#include<cstring>using namespace std;const int maxnode = 1e5+10;char s[maxnode];int sa[maxnode], t[maxnode], t2[maxnode], c[maxnode];void buildsa(int n){ int m = 256, *x = t, *y = t2; //基数排序 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 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) c[i] = 0; for(int i = 0; i < n; ++ i) c[x[y[i]]] ++; for(int i = 0; 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); p = 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]?p-1:p++; if(p >= n) break; m = p; }}int rank[maxnode], height[maxnode];void getheight(int n){ memset(height, 0, sizeof height); int k = 0; for(int i = 0 ; i < n ; ++ i) rank[sa[i]] = i; for(int i = 0 ; i < n ; ++ i) { if(k) k--; if(rank[i]==0) continue; int j = sa[rank[i]-1]; while(s[i+k] == s[j+k]) k++; height[rank[i]] = k; }}int main(){ //freopen("in.txt","r",stdin); int m; while(~scanf("%d", &m)&&m) { scanf("%s",s); if(m==1) { printf("%d 0\n", strlen(s)); continue; } int n = strlen(s) + 1; buildsa(n); getheight(n); int left = 0, right = n*2, mid; int pos = -1, len = 1; while(left<right-1) { mid = (right + left)/2; bool flag = false; int post = -1, numt = 1; for(int i = 2 ; i <= n ; ++ i) { if(height[i]>=mid) { numt ++; post = max(post, sa[i]); post = max(post, sa[i-1]); if(numt>=m) { if(len<mid || (len==mid)&&pos<post ) { pos = post; len = mid; } flag = true; } } else { post = -1; numt = 1; } } if(flag) { left = mid; } else { right = mid; } } if(pos==-1) { printf("none\n"); } else { printf("%d %d\n", len, pos); } } return 0;}
- hdu 4080 Stammering Aliens - 后缀数组
- HDU 4080 Stammering Aliens(后缀数组)
- HDU 4080 Stammering Aliens && 后缀数组
- [后缀数组+二分] hdu 4080 Stammering Aliens
- HDU 4080 Stammering Aliens (后缀数组 + 二分答案)
- HDU 4080 Stammering Aliens(后缀数组+二分)
- HDU 4080 Stammering Aliens
- Hdu 4080 & Poj 3882 Stammering Aliens (后缀数组 可重叠k次最长重复子串)
- ZOJ3395 Stammering Aliens 二分+后缀数组
- UVALive - 4513 Stammering Aliens(后缀数组模板)
- UVA 12206 - Stammering Aliens(后缀数组)
- hdu4080---Stammering Aliens(后缀数组+二分)
- UVALive4513 Stammering Aliens(哈希法,后缀数组)
- UVA 12206 Stammering Aliens(后缀数组+二分)
- hdu 4080 Stammering Aliens ( 后缀数组 求最长的至少出现m次可重叠子串)
- hdu 4080 Stammering Aliens 二分 hash
- POJ 3882 Stammering Aliens 后缀数组height应用
- UVALive 4513 (LA 4513) Stammering Aliens 后缀数组 或 hash
- JAVA面试题解惑系列 – final、finally和finalize的区别
- verilog中的 阻塞赋值 与 非阻塞赋值 详解。
- 【交互】MFC架构分析
- windows下的正则式工具介绍之一:RegexBuddy
- ocp-047-14 22 40 grant revoke role
- HDU 4080 Stammering Aliens && 后缀数组
- 3.(学习)C++
- Linux下minicom的配置和使用方法
- 区分Activity的四种加载模式
- Xcode如何打包ipa安装包
- 如何彻底删除mysql-注册表问题
- 黑马程序员-String、StringBuffer、StringBuilder
- 4.(学习)C++
- URL参数带中文,后台接收乱码解决方案