首页 > 代码库 > hdu 4821 String(字符串hash)
hdu 4821 String(字符串hash)
题目链接:hdu 4821 String
题意:
给你一个字符串,问你有多少子串,满足长度为m*len,并且这个子串能分成m个len长度的不同串。
题解:
BKDRhash+map来判重。注意的是要以len长分类来扫,这样才不会超时。
1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=a;i<=b;++i) 3 using namespace std; 4 typedef unsigned long long ull; 5 const int str_len=1e5+7; 6 struct string_hash 7 { 8 const static int seed=31; 9 int len; 10 ull h[str_len],b[str_len]; 11 inline int idx(char x) 12 { 13 return x-‘a‘+1; 14 } 15 void init() 16 { 17 h[0]=0,b[0]=1; 18 F(i,1,str_len-1)b[i]=b[i-1]*seed; 19 } 20 void ins(char *s)//从1开始。 21 { 22 len=strlen(s+1); 23 F(i,1,len)h[i]=h[i-1]*seed+idx(s[i]); 24 } 25 inline ull ask(int l,int r){return h[r]-b[r-l+1]*h[l-1];}//区间段hash值 26 }str; 27 28 int m,l,ans; 29 char s[str_len]; 30 map<ull,int>cnt; 31 int main() 32 { 33 str.init(); 34 while(~scanf("%d%d",&m,&l)) 35 { 36 scanf("%s",s+1); 37 str.ins(s),ans=0; 38 for(int i=1;i<=l&&i+m*l<=str.len;i++) 39 { 40 cnt.clear(); 41 for(int j=i;j<i+m*l;j+=l)cnt[str.ask(j,j+l-1)]++; 42 ans+=(cnt.size()==m); 43 for(int j=i+m*l;j+l-1<=str.len;j+=l) 44 { 45 cnt[str.ask(j,j+l-1)]++; 46 ull tmp; 47 cnt[tmp=str.ask(j-m*l,j-m*l+l-1)]--; 48 if(cnt[tmp]==0)cnt.erase(tmp); 49 ans+=(cnt.size()==m); 50 } 51 } 52 printf("%d\n",ans); 53 } 54 return 0; 55 }
hdu 4821 String(字符串hash)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。