Problem Description
There is a string
S.
S only contain lower case English character.
(10≤length(S)≤1,000,000)
How many substrings there are that contain at least k(1≤k≤26) distinct characters?
How many substrings there are that contain at least k(1≤k≤26) distinct characters?
Input
There are multiple test cases. The first line of input contains an integer
T(1≤T≤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≤k≤26).
The first line contains string S.
The second line contains a integer k(1≤k≤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,那么就从那个子串的开头开始删去字符,根据删除的字符出现的次数,做出相应的判断。
如果用map判断是否出现过会超时。
#include<cstring>
#include<string>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<stack>
using namespace std;
typedef long long ll;
const int N=1e6+9;
char s[N];
int k;
int vis[300];
int main()
{
//freopen("f.txt","r",stdin);
int T;scanf("%d",&T);
while(T--){
scanf("%s%d",s,&k);
int slen=strlen(s);
if(k==1){
printf("%I64d\n",(ll)slen*(slen+1)/2);continue;
}
int head=0;
ll ans=0;
int cnt=0;
memset(vis,0,sizeof(vis));
for(int i=0;i<slen;i++){
if(vis[s[i]]>0){
vis[s[i]]++;
continue;
}
vis[s[i]]=1;
cnt++;
if(cnt==k){
while(head<i){
ans+=slen-i;
if(vis[s[head]]==1){
vis[s[head]]=0;
head++;
cnt--;
break;
}
else{
vis[s[head]]--;head++;
}
}
}
}
printf("%I64d\n",ans);
}
return 0;
}