题目链接:
hdu:http://acm.hdu.edu.cn/showproblem.php?pid=5672
bc(中文):http://bestcoder.hdu.edu.cn/contests/contest_chineseproblem.php?cid=692&pid=1002
题解:
对于每一个st(0<=st<len),求最小的ed使得str[st...ed]子串刚好包含k个不同的字母,然后累加起来就行了,由于st,ed都是单调不减的,时间复杂度为O(n+n)=O(n)
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 typedef long long LL; 7 const int maxn=1010101; 8 9 char str[maxn]; 10 int cnt[33]; 11 int k; 12 13 void init(){ 14 memset(cnt,0,sizeof(cnt)); 15 } 16 17 int main(){ 18 int tc; 19 scanf("%d",&tc); 20 while(tc--){ 21 init(); 22 scanf("%s",str); 23 scanf("%d",&k); 24 int len=strlen(str); 25 LL ans=0; 26 int sum=0; 27 int ed,st; 28 for(ed=-1,st=0;ed<len;){ 29 if(sum>=k){ 30 ans+=len-ed; 31 cnt[str[st]-'a']--; 32 if(cnt[str[st]-'a']==0) sum--; 33 st++; 34 }else{ 35 ed++; 36 if(cnt[str[ed]-'a']==0) sum++; 37 cnt[str[ed]-'a']++; 38 } 39 } 40 printf("%lld ",ans); 41 } 42 return 0; 43 }