HDU 4821 String(字符串哈希)
2015-10-29 10:31
435 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4821
题意:
给出M和L,和一个字符串S。要求找出S的子串中长度为L*M,并且可以分成M段,每段长L,并且M段都不相同的子串个数。哈希过后,
若Hash[i]-Hash[i+L]*K[L] == Hash[j]-Hash[j+L]*k[L], 则说明串s[i...i+L-1]
和串s[j....j+L-1]是相同的。
题意:
给出M和L,和一个字符串S。要求找出S的子串中长度为L*M,并且可以分成M段,每段长L,并且M段都不相同的子串个数。哈希过后,
若Hash[i]-Hash[i+L]*K[L] == Hash[j]-Hash[j+L]*k[L], 则说明串s[i...i+L-1]
和串s[j....j+L-1]是相同的。
#include<stdio.h> #include<string.h> #include<map> #include<algorithm> using namespace std; typedef unsigned long long ULL; #define SEED 31//这个数一般为素数 如1331, 1000000007等 const int maxn = 1e5 + 100; ULL Hash[maxn], K[maxn]; map<ULL, int> st; char s[maxn]; int main() { int M, L, len; while(~scanf("%d%d", &M, &L)) { scanf("%s", s); len = strlen(s); Hash[len] = 0; K[0] = 1; for(int i = 1; i <= L; i++) K[i] = K[i-1] * SEED; for(int i = len-1; i >= 0; i--) { Hash[i] = Hash[i+1]*SEED + (s[i]-'a'+1); } int res = 0; for(int i = 0; i<L && i+M*L<len; i++) { st.clear(); for(int j = i; j < M*L+i; j+=L) { st[Hash[j]-Hash[j+L]*K[L]]++; } if(st.size() == M) res++; for(int j = M*L+i; j <= len-L; j+=L) { int head = j - M*L; st[Hash[head]-Hash[head+L]*K[L]]--; if(st[Hash[head]-Hash[head+L]*K[L]] == 0) st.erase(Hash[head]-Hash[head+L]*K[L]); st[Hash[j]-Hash[j+L]*K[L]]++; if(st.size() == M) res++; } } printf("%d\n", res); } return 0; }
相关文章推荐
- Java(Android)线程池
- owncloud配置swift外接存储
- LaTeX求和积分的上下限设置
- 水文
- 晴
- 防御性判断
- git使用
- zoj 3593 One Person Game
- win7系统的wifi密码忘记了怎么办?如何找回?
- 首个 C++ 编译器诞生 30 周年了,来听听 C++ 之父畅谈 C++
- Java中用JXL导出Excel代码详解
- 文章标题
- iOS开发 正确选择图片加载方式
- google-io-2014
- Java面试中经常问到的算法题
- Android Fragment 解析
- 复制表结构和数据SQL语句
- 报个到
- ecshop重写url地址
- 转:jxl导出excel(合并单元格)