题目大意:

希望找到连续的长为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\n" , ret);
63     }
64     return 0;
65 }

 

 posted on 2015-06-10 19:08  Love风吟  阅读(204)  评论(0编辑  收藏  举报