String
problem DescriptionThere is a stringS.SOnly contain lower case 中文版 character.(≤lengtH(S)≤1, )
How many substrings there is that contain at least k(1≤k≤) distinct characters?
InputThere is multiple test cases. The first line of input contains an integerT(1≤t≤) indicating the number of test cases. For each test case:
The first line contains stringS.
The second line contains a integer k(1≤k≤) .
OutputFor each test case, output the number of substrings that contain at least k dictinct characters.
Sample Input2abcabcabca4abcabcabcabc3
Sample Output055
Test Instructions:Have a10\leq10≤ length\leq 1,000,000≤1,000,00 0strings, consisting only of lowercase letters. How many substrings are available, containing at least K (1 \leq k \leq)K(1≤k≤26) different letters?
puzzle:
There is an obvious nature: if the substring(I,J)(I,J) contains at leastKK a different character, then the substring(I,k), (J < K < length)< Span class= "Mopen" > (i,k , (j <k<le< Span class= "Mord mathit" >ngthk k different characters 。
Therefore, for each left boundary, you can find the minimum right boundary to satisfy the condition, and you will be able to o (1) < span class= "Strut" > O (1) all the qualifying substrings starting with the left boundary are counted in time.
Looking for this right boundary, is the classic catch-up method (ruler method, double-pointer approach) problem. Maintain two pointers (array subscript), update the left and right boundaries in turn, and accumulate the answers. Complexity O (Length (S))o(lengtH(s)).
#include <iostream>#include<cstdio>#include<cmath>#include<string>#include<queue>#include<algorithm>#include<stack>#include<cstring>#include<vector>#include<list>#include<Set>#include<map>#pragmaComment (linker, "/stack:102400000,102400000")using namespacestd;Const intN = 1e6+Ten, M =30005, mod = 1e9 +7, INF =0x3f3f3f3f; typedefLong Longll;intt,k,h[ -];CharS[n];intMain () {scanf ("%d",&T); while(t--) {scanf ("%s%d", s+1,&k); intn = strlen (s+1); memset (H,0,sizeof(H)); intR =0, cnt =0; ll ans=0 ; for(intL =1; l<=n;l++) { while(cnt<k&&r<N) {++R; if(++h[s[r]]==1) cnt++; } if(cnt<k) Break; Ans= ans+n-r+1; if(--h[s[l]] = =0) --CNT; } cout<<ans<<Endl; } return 0;}
HDU 5672 String Ruler method for catching up