题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4821
用到了BKD字符串哈希的方法,一直不是很会哈希,总是用map,但是很显然,map并不是万能的。
用哈希的方法可以递推的求出所有子串的哈希值,最后用map维护答案即可;注意下long long
#include<iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<cmath> #include<vector> #include<map> #include<climits> using namespace std; typedef long long ll; typedef unsigned long long llu; const int maxd=1e5+5; const int seed=31; const int INF = 0xffffffff; ///=================== char str[maxd]; llu k[maxd],_hash[maxd]; map<llu,int> s; int M,L; void BKD_hash(int len) { 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+(str[i]-'a'+1); } int main() { while(scanf("%d%d",&M,&L)==2) { scanf("%s",str); int len=strlen(str),cnt=0; BKD_hash(len); for(int i=0; i<L && M*L+i<len; i++) { s.clear(); for(int j=i; j<M*L+i; j+=L) { llu id=_hash[j]-_hash[j+L]*k[L]; s[id]++; } if(s.size()==M) cnt++; for(int j=M*L+i; j<len-L+1; j+=L) { llu head=j-M*L; llu id=_hash[head]-_hash[head+L]*k[L]; s[id]--; if(s[id]==0) s.erase(id); llu id2=_hash[j]-_hash[j+L]*k[L]; s[id2]++; if(s.size()==M) cnt++; } } printf("%d\n",cnt); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-09-29 18:06:40