1. 程式人生 > >String HDU

String HDU

String

題意:有一條只由小寫字母構成的字串,問有多少子串中包含不少於k個不同字元;

思路:若以l為起點的區間[l, r]中,有k個不同字元,且r處的字元就是第k個不同的字元,那麼r後邊的區間也一定 至少k個不同字元;

那麼,以l為起點的區間中,包含至少k個不同字元的區間有n-r個(n是原串長度,下標由0開始);

就用尺取法維護這樣一個區間;

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
char s[maxn];
int vis[30], k, cnt;
bool check(int x){
	if(vis[s[x]-'a']) return cnt<k;
	return cnt+1<k;
}
int main(){
	int T;
	scanf("%d", &T);
	while(T--){
		scanf("%s", s);
		scanf("%d", &k);
		memset(vis, 0, sizeof(vis));
		long long ans=0;
		int len=strlen(s);
		vis[s[0]-'a']++;
		cnt=1;
		for(int i=0, j=0; i<len; i++){
			while(check(j+1)&&j+1<len){
				j++;
				if(vis[s[j]-'a']==0) cnt++; 
				vis[s[j]-'a']++;
			}
			if(j>=len-1) break;
			ans+=(len-j-1);
			vis[s[i]-'a']--;
			if(vis[s[i]-'a']==0) cnt--;
		}
		printf("%lld\n", ans);
	}
	return 0;
}