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 leastk(1≤k≤26)
distinct characters?
How many substrings there are that contain at least
Input
There are multiple test cases. The first line of input contains an integerT(1≤T≤10)
indicating the number of test cases. For each test case:
The first line contains stringS .
The second line contains a integerk(1≤k≤26) .
The first line contains string
The second line contains a integer
Output
For each test case, output the number of substrings that contain at leastk
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 ",(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 ",ans); } return 0; }