解题思路:双指针技巧中的左右指针,确定两个指针,l与r,子串的左边界一旦确定,让 l 固定,让r先后移动,直到k个字符出现,r前部分的字符对子字符没有影响,所以从 l 开始的子字符串 为 lenght-r+1,就如此遍历左端点就可以了,将结果累加起来
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <cstring>
using namespace std;
#define ll long long
const int maxn=1e6+7;
const ll INF=1e9+7;
char s[maxn];
ll vis[maxn];
ll n;
int main(){
ll t;
scanf("%lld",&t);
while(t--){
memset(vis,0,sizeof(vis));
ll ans=0;
scanf("%s",&s);
scanf("%lld",&n);
ll l=0;
ll r=0;
ll k=0;
ll len=strlen(s);
while(l<len){
while(r<len&&k<n){
if(vis[s[r]-'0']==0)
k++;
vis[s[r]-'0']++;
r++;
}
if(k<n) break;
ans+=len-r+1;
vis[s[l]-'0']--;
if(vis[s[l]-'0']==0)
k--;
l++;
}
printf("%lld\n",ans);
}
return 0;
}