POJ3261-哈希
2015-08-20 15:21
337 查看
这个题让求至少出现K次的最大长度的子串,属于最大化最小值问题,首先应该想到二分求字串的长度,二分的过程是O(logN)的,注意judge的时候怎样判断是否满足情况以及满足情况后l,r的变化。可以给每一个子串定一个hash值,判断所有hash值中相同的是否超过K个,hash方法同BDKshash。。POJ数据略水。。a[i]的值远远没有到100W。。poj的字符串题一直感觉数据都不太好。。红着脸水过。。
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int maxn = 20010; typedef long long ll; int n,k,seed = 131; ll base[maxn]; ll one[maxn],hash[maxn]; int a[maxn]; bool judge(int x) { for(int i = 1; i <= n-x+1; ++i) { hash[i] = one[i+x-1]-one[i-1]*base[x]; } int j = n-x+1; sort(hash+1,hash+1+j); int sum = 1; for(int i = 1; i <= n-x+1; ++i) { if(hash[i] == hash[i+1]) sum++; else{ if(sum >= k) return true; else sum = 1; } } if(sum >= k) return true; else return false; } int main() { scanf("%d%d",&n,&k); base[0] = 1; for(int i = 1; i <= n; ++i) base[i] = base[i-1]*seed; for(int i = 1; i <= n; ++i) scanf("%d",a+i); one[0] = 0; for(int i = 1; i <= n; i++) one[i] = one[i-1]*seed+a[i]; int l = 1,r = n,mid,ans; while(l <= r) { int mid = l +(r-l)/2; if(judge(mid)) l = mid+1,ans = mid; else r = mid-1; } printf("%d\n",ans); }
相关文章推荐
- Atitit. 软件设计 模式 变量 方法 命名最佳实践 vp820 attilax总结命名表大全
- sublime text侧边栏
- 选择排序
- 指针常量和常量指针
- 图数据库之Cypher语言
- SSH框架总结-框架分析
- sublime text侧边栏
- linux下创建和删除软、硬链接
- jdbc事务处理
- HBuilder快捷键
- json 在线转换
- 欢迎使用CSDN-markdown编辑器
- Android初学习 - 编译时不生成odex文件的方法
- CentOS 6.3 64位 搭建SVNServer服务器
- maven中把依赖的JAR包一起打包
- Codeforces Round #254 (Div. 2) A. DZY Loves Chessboard
- [Jobdu] 题目1361:翻转单词顺序
- 多按钮事件处理
- 设置文本排序及对齐
- PAT 1051. Pop Sequence (25)