String
Description
There is a string
S
.
S
only contain lower case English character.
(10 \leq length(S) \leq 1,000,000)
How many substrings there are that contain at least k(1 \leq k \leq 26) distinct characters?
How many substrings there are that contain at least k(1 \leq k \leq 26) distinct characters?
Input
There are multiple test cases. The first line of input contains an integer
T (1\leq T\leq 10)
indicating the number of test cases. For each test case:
The first line contains string S .
The second line contains a integer k(1 \leq k \leq 26) .
The first line contains string S .
The second line contains a integer k(1 \leq k \leq 26) .
Output
For each test case, output the number of substrings that contain at least
k
dictinct characters.
Sample Input
2 abcabcabca 4 abcabcabcabc 3
Sample Output
0 55
尺取法,就是每次选取中间的一小段,就相当于在一个直尺上选取一小段一样,就是前跑后追,不符合条件的时候每次往后面添加,当符合条件就从前面删除,删除到不符合条件就继续后加,然后依次类推,只要将整条链遍历一遍,就能得到结果。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
using namespace std;
char str[1000100];
int main()
{
int t;
cin >> t;
while(t--)
{
int n;
memset(str,0,sizeof(str));
scanf("%s%d",str,&n);
int m[26] = {0};
int len = strlen(str);
int i = 0,s = 0,num = 0;
long long int res = 0;
while(1)
{
while(i < len && num < n)
{
if(m[str[i++] - 'a']++ == 0)
num++;
}
if(num < n)
break;
res += len - i + 1; // 找到符合条件的以后,后面可以随意添加都符合条件,所以加上 len - i + 1
if(--m[str[s++] - 'a'] == 0)
num--;
}
printf("%I64d\n",res);
}
return 0;
}