HDU 4821 String 解题报告(哈希)
来源:互联网 发布:中国汽车年度销量数据 编辑:程序博客网 时间:2024/06/10 19:39
String
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 773 Accepted Submission(s): 216
Problem Description
Given a string S and two integers L and M, we consider a substring of S as “recoverable” if and only if
(i) It is of length M*L;
(ii) It can be constructed by concatenating M “diversified” substrings of S, where each of these substrings has length L; two strings are considered as “diversified” if they don’t have the same character for every position.
Two substrings of S are considered as “different” if they are cut from different part of S. For example, string "aa" has 3 different substrings "aa", "a" and "a".
Your task is to calculate the number of different “recoverable” substrings of S.
(i) It is of length M*L;
(ii) It can be constructed by concatenating M “diversified” substrings of S, where each of these substrings has length L; two strings are considered as “diversified” if they don’t have the same character for every position.
Two substrings of S are considered as “different” if they are cut from different part of S. For example, string "aa" has 3 different substrings "aa", "a" and "a".
Your task is to calculate the number of different “recoverable” substrings of S.
Input
The input contains multiple test cases, proceeding to the End of File.
The first line of each test case has two space-separated integers M and L.
The second ine of each test case has a string S, which consists of only lowercase letters.
The length of S is not larger than 10^5, and 1 ≤ M * L ≤ the length of S.
The first line of each test case has two space-separated integers M and L.
The second ine of each test case has a string S, which consists of only lowercase letters.
The length of S is not larger than 10^5, and 1 ≤ M * L ≤ the length of S.
Output
For each test case, output the answer in a single line.
Sample Input
3 3abcabcbcaabc
Sample Output
2
Source
2013 Asia Regional Changchun
解题报告: 求连续m个长度为 l 的子串两两不相同的数量。
首先,对比长度为 l 的字串是否相同,我们可以用字符串哈希的方法。然后我们使用Hash表,将(0, l-1)的子串哈希值插入哈希表,标记为1,(l, 2l - 1)的子串哈希值插入哈希表,标记为2。。。如果发现某次的哈希值已经标记过,且标记的值与当前的将要标记的值的差值小于m,那么说明这里有部分m个长度为 l 的连续串不符合条件。最后用总数减去不符合条件的即可。代码如下:
#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <cmath>#include <queue>#include <vector>#include <map>#include <set>#include <string>#include <iomanip>#include <cassert>using namespace std;//#pragma comment(linker, "/STACK:1024000000,1024000000")#define ff(i, n) for(int i=0;i<(n);i++)#define fff(i, n, m) for(int i=(n);i<=(m);i++)#define dff(i, n, m) for(int i=(n);i>=(m);i--)#define bit(n) (1LL<<(n))typedef long long LL;typedef unsigned long long ULL;void work();int main(){#ifdef ACM freopen("in.txt", "r", stdin);#endif // ACM work();}void nextInt(int & x){ char ch; while(ch = getchar(), isdigit(ch) == false); x = 0; while(x = 10 * x + ch - '0', ch = getchar(), isdigit(ch) == true);}/*****************************************华丽分割线**********************************************/int m, l;/********************************************************* * 无清空哈希表。闭哈希,long long 对比,保存Size大小。* * 可直接遍历哈希状态,每次使用时init下。 * *********************************************************/template<int Size>struct HashTable{ int v[Size]; int h[Size]; int n[Size]; ULL s[Size]; int size, id, num; void init() { ++id; size = 0; } int push(ULL ss) { num++; int i = ss % Size; while (v[i] == id && s[h[i]] != ss) if(++i == Size) i = 0; if (v[i] == id) { int ret = num - n[h[i]]; n[h[i]] = num; return ret; } else { s[size] = ss; n[size] = num; h[i] = size++; v[i] = id; return Size; } }};HashTable<1000003> ht;ULL powULL(ULL a, int b){ ULL ret = 1; while(b) { if(b&1) ret = ret * a; a = a * a; b >>= 1; } return ret;}/********************************************************* * 字符串哈希大法 * *********************************************************/template<int Size>struct HashString{ ULL h[Size]; ULL powull; void init(char * s, int len = -1) { powull = powULL(29, l); if(len == -1) len = strlen(s); ff(i, len) h[i+1] = h[i] * 29 + s[i] - 'a'; } ULL get(int sta, int len) { return h[sta + len] - h[sta] * powull; }};HashString<111111> hs;char str[111111];void work(){ while(scanf("%d%d", &m, &l) == 2) { scanf("%s", str); int len = strlen(str); hs.init(str, len); int ans = 0; ff(sta, l) { ht.init(); int ti = (len - sta) / l; int mt = ti - m + 1; if (mt <= 0) continue; int res = 0; int wws = -1, wwe = -2; ff(i, ti) { int sub = ht.push(hs.get(sta + i * l, l)); if (sub >= m) continue; int ws = max(0, i-m+1); int we = min(i-sub, mt-1); if (ws <= wwe) { wwe = max(wwe, we); } else { res += wwe - wws + 1; wws = ws, wwe = we; } } res += wwe - wws + 1; ans += mt - res; } printf("%d\n", ans); }}
0 0
- HDU 4821 String 解题报告(哈希)
- HDU 4681 String 解题报告
- HDU GCC(HDU 3123)解题报告
- Interleaving String解题报告
- HDU 1915 Arne Saknussemm (解题报告)
- HDU 1908 Double Queue (解题报告)
- hdu 1166 敌兵布阵 (解题报告)
- HDU 1251 统计难题(解题报告)
- HDU:2013解题报告(递推)
- (贪心)HDU 1789 解题报告
- hdu 1422 - 重温世界杯(解题报告)
- hdu 1176 - 免费馅饼 (解题报告)
- hdu 2084 - 数塔(解题报告)
- hdu 5326 - Work(递归)解题报告
- hdu 5120 - Intersection(解题报告)
- hdu 1071 - The area(解题报告)
- hdu 1106 - 排序(解题报告)
- HDU 3342 解题报告
- Jsoup抓取图片功能代码学习
- PHP中用jQuery 的操作POST方法提交数据(用login测试)
- Android 用Gradle构建你的Android程序
- Java 从基础到进阶学习之路---类编写以及文档注释.
- CVE-2014-6283: Privilege Escalation Vulnerability and Potential Remote Code Execution in SAP Adaptiv
- HDU 4821 String 解题报告(哈希)
- 【学习4】Cocos2d-x 常用控件之Sprite
- 浅析连续子向量,子数组和(一维,二维)问题
- 背包算法问题
- 《Systems Performance: Enterprise and the Cloud》读书笔记系列(三) —— 第二章(二)
- [android]Mac OS环境下真机调试的环境配置
- Android:ListView常见错位之CheckBox错位
- Flume-ng+Kafka+storm的学习笔记
- UVa 442 Matrix Chain Multiplication(矩阵链乘,模拟栈)