题目大意:
希望找到连续的长为m*l的子串,使得m个l长的子串每一个都不一样,问能找到多少个这样的子串
简单的字符串hash,提前预处理出每一个长度为l的字符串的hash值
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 #include <map> 6 #include <set> 7 8 using namespace std; 9 #define N 100010 10 #define base 31 11 typedef unsigned long long ULL; 12 map<ULL , int> _map; 13 int m , l; 14 ULL fac[N] , val[N]; 15 char str[N]; 16 17 void init() 18 { 19 fac[0] = 1; 20 for(int i=1 ; i<=100000 ; i++) fac[i] = fac[i-1]*base; 21 } 22 23 int main() 24 { 25 #ifndef ONLINE_JUDGE 26 freopen("a.in" , "r" , stdin); 27 #endif // ONLINE_JUDGE 28 init(); 29 while(~scanf("%d%d" , &m , &l)) 30 { 31 scanf("%s" , str); 32 int len = strlen(str) , cnt , same , ret; 33 ULL cur = 0; 34 for(int i=0 ; i<len ; i++){ 35 if(i>=l) cur = cur-fac[l-1]*str[i-l]; 36 cur=cur*base+str[i]; 37 if(i>=l-1) val[i-l+1] = cur; 38 //cout<<i-l+1<<" "<<val[i-l+1]<<endl; 39 } 40 ret=0; 41 for(int i=0 ; i<l ; i++){ 42 _map.clear(); 43 cnt = 0 , same = 0; 44 for(int j=i ; j<len ; j+=l){ 45 if(j+l-1>=len) break; 46 if(cnt >= m){ 47 int la = j-m*l; 48 int t = _map[val[la]]--; 49 if(t==2) same--; 50 } 51 int t = _map[val[j]]++; 52 if(t==1) same++; 53 cnt++; 54 // cout<<j<<" "<<cnt<<" "<<endl; 55 if(cnt >= m && same==0){ 56 ret++; 57 // cout<<j<<endl; 58 } 59 60 } 61 } 62 printf("%d " , ret); 63 } 64 return 0; 65 }