Description

nodgd写了一篇文章,自认为这是一篇好文章。nodgd的文章由𝑛个小写英文字母组成。文章的一个子串指的是文章中的一段连续的字母,子串的长度就是这一段的字母个数。nodgd在文章中用了排比、对偶、前后照应之类的手法,所以就有很多个子串是相同或者相近的。为了向大家证明这是一篇好文章,nodgd决定给自己的文章进行评分。nodgd首先确定了一个整数𝑚,然后统计出文章中有多少个不相同的长度为𝑚的子串,这个数量就是文章的评分。
然而,nodgd懒得老老实实计算这个评分了,就把任务丢给了你。
 

Input

第一行包含两个整数𝑛,𝑚,表示文章的长度和需要统计的子串长度。
第二行包含一个长度为𝑛的只包含小写字母的字符串。

Output

输出一行一个整数,表示文章的评分。
 

Sample Input

输入1:
5 3
aaaab

输入2:
9 3
abcabacba

Sample Output

输出1:
2
样例解释1:
长度为3的子串有3个,分别是aaa,aaa,aab,其中不同的只有2个。
输出2:
7
样例解释2
共有7个长度为3的子串,每个长度为3的子串都不同。
 

Data Constraint

对于30%的数据,1≤𝑚≤𝑛≤200;
对于50%的数据,1≤𝑚≤𝑛≤2000;
对于另外20%的数据,1≤𝑚≤50≤𝑛≤200000;
对于100%的数据,1≤𝑚≤𝑛≤200000。
 
做法:一开始还以为是字典树,然后只有50分。。(空间不够,链表打法有70),然后就字符串hash暴力啦(能水过很多字符串匹配问题诶╭(╯^╰)╮)
 
代码如下:
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <string>
 5 #include <algorithm>
 6 #include <cstdlib>
 7 #define LL long long
 8 #define MO 1000000007
 9 #define mo 1000000009
10 #define N 200009
11 #define P 61
12 #define p 97
13 using namespace std;
14 char s[N];
15 struct arr
16 {
17     LL H, h;
18 }hash[N];
19 LL ans, n, m;
20 LL HVAL[N], mp[N], MP[N], hval[N];
21 
22 LL Cmp(arr x, arr y)
23 {
24     if (x.H == y.H)    return x.h < y.h; 
25     return x.H < y.H;
26 }
27 
28 void Pre_work()
29 {
30     mp[0] = 1, MP[0] = 1;
31     for (int i = 1; i <= n; i++)
32     {
33         HVAL[i] = (HVAL[i - 1] * P + (s[i] - 'a' + 1)) % MO;
34         hval[i] = (hval[i - 1] * p + (s[i] - 'a' + 1)) % mo;
35          mp[i] = (mp[i - 1] * p) % mo, MP[i] = (MP[i - 1] * P) % MO;
36     }
37 }
38 
39 void Getnum(LL l, LL r, LL ain)
40 {
41     hash[ain].h = (hval[r] - hval[l - 1] * mp[r - l + 1] % mo + mo) % mo;
42     hash[ain].H = (HVAL[r] - HVAL[l - 1] * MP[r - l + 1] % MO + MO) % MO;
43 }
44 
45 int main()
46 {
47     freopen("article.in", "r", stdin);
48     freopen("article.out", "w", stdout);
49     scanf("%d%d", &n, &m);
50     cin >> s + 1;
51     Pre_work();
52     for (int i = 1; i <= n - m + 1; i++)
53         Getnum(i, i + m - 1, i);
54     sort(hash + 1, hash + n - m + 2, Cmp);
55     for (int i = 1; i <= n - m + 1; i++)
56         if (hash[i].h == hash[i + 1].h && hash[i].H == hash[i + 1].H)    continue;
57         else ans++;
58     printf("%d", ans);
59 }
View Code