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
数学组合,直接模拟计数。 按顺序遍历字符串,记录出现的不同字母的个数cnt,和每种字母出现的数量。 当cnt==k时,以当前字符串为子串的子串共有len-i个。然后将最左边的减去,依次记录下去。
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
char s[1000010];
int v[30];
int main()
{
int k,t,i,j;
scanf("%d",&t);
while(t--)
{
scanf("%s%d",s,&k);
int len=strlen(s);
int c=0,l=0;
long long ans=0;
memset(v,0,sizeof(v));
for(i=0; i<len; i++)
{
int t=s[i]-'a'; //转化为数字,便于计算
if(v[t]) //如果出现过此字符,标记出现过几次
v[t]++;
else //如果没有出现过此字符,标记出现,字符数加1
{
v[t]++;
c++;
}
if(c==k)
{//如果字符数等于要求的那个数,以当前字符串为子串的子串共有len-i个
ans+=len-i;
while(1)
{
t=s[l]-'a'; //把字符取出
v[t]--; //数量减去一个
l++; //再处理下一个
if(!v[t]) //如果字符的次数不为1
{
c--; //把字符数-1
break;
}
else //如果只有一个,再加一次
ans+=len-i;
}//直到左边的字符串减掉完
}
}
printf("%I64d\n",ans);
}
return 0;
}