hdu-4821(BKDRHash字符串哈希)
来源:互联网 发布:大学生java培训机构 编辑:程序博客网 时间:2024/04/29 05:31
传送门:http://acm.hdu.edu.cn/showproblem.php?pid=4821
String
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.
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.
3 3abcabcbcaabc
2
题目大意:有一个字符串s,问有几个满足如下条件的子串:
1、子串的长度为m*L
2、这m个长为L的子子串各个不相等
基本思路:
用BKDRHash的哈希方法求出字符串的哈希值,然后剩下的就查找有几个满足条件的子串就行了,在记录其中一个m*L的子串时,用map记录有多少不同的长为L的子子串。
#include <iostream>#include <cstring>#include <cmath>#include <cstdlib>#include <algorithm>#include <cstdio>#include <map>using namespace std;typedef unsigned long long LL;///无符号形长整数溢出时自动取模const int MAX=1e5+7,seed=31;char s[MAX];LL base[MAX],h[MAX];map<LL,int>mp;LL BKDRHash(int l,int r)///这是求每个子串的哈希值的方法{ return h[r]-h[l-1]*base[r-l+1];}int main(){ int m,l; base[0]=1; for(int i=1;i<=MAX;i++)base[i]=base[i-1]*seed;///基数 while(~scanf("%d%d",&m,&l)) { int ans=0; scanf("%s",s+1); int len=strlen(s+1); h[0]=0; for(int i=1;i<=len;i++) h[i]=h[i-1]*seed+s[i]-'a';///对整个字符串求哈希值 ///下面通过map来记录充计有多少对符合条件的m*l长度的字符串,个人感觉这里类似于尺取法 for(int i=1;i<=l&&i+m*l-1<=len;i++)///从i开始连续的m*l长度的子串,注意i<=l跳出循环(因为当i==l时,之后的情况都已经查询了) { mp.clear(); for(int j=i;j<=i+m*l-1;j+=l) { LL x=BKDRHash(j,j+l-1); mp[x]++; } if(mp.size()==m)ans++; for(int j=i+m*l;j+l-1<=len;j+=l) { LL x=BKDRHash(j,j+l-1); mp[x]++; LL y=BKDRHash(j-m*l,j-m*l+l-1); mp[y]--; if(mp[y]==0)mp.erase(y); if(mp.size()==m)ans++; } } printf("%d\n",ans); } return 0;}
阅读全文
0 0
- hdu-4821(BKDRHash字符串哈希)
- HDU 1800 哈希算法BKDRHash
- [HDU]4821 String (BKDRhash+成段移动法判字符串)
- 2013 Asia Regional Changchun HDU 4821 String (BKDRhash+成段移动法判字符串)
- 字符串Hash (BKDRHash)
- hdu4821 字符串 hash (bkdrhash)
- hdu4821 String 字符串hash(bkdrhash)
- BKDRHash
- hdu 1800 字符串的hash(BKDRHash 模版)大牛推荐的函数
- HDU 4821 字符串哈希
- 通过BKDRHASH将字符串转化为数值类型
- HDU 4821 String 字符串哈希
- HDU 4821 String 字符串哈希
- HDU--4821(字符串哈希)
- HDU 4821 String(字符串哈希)
- hdu 4821 滑动窗口+字符串哈希
- 希表之bkdrhash算法解析及扩展
- 2013ICPC 长春I HDU 4821 String 字符串哈希
- 导航栏标题
- CentOS6 安装并破解confluence
- 前端模块化,AMD与CMD的区别
- Android 设置按钮点击时候颜色背景的改变
- centos7下安装rar解压软件
- hdu-4821(BKDRHash字符串哈希)
- xsi:schemaLocation有何作用
- js建立数组,删除数组元素,js向数组添加map集合
- 机器学习之K-近邻算法
- HTML5 教程
- Vue之slot内容分发
- jsp+sql实现分页
- MapDB 教程三
- 哈工大LTP初步学习