2 abcabcabca 4 abcabcabcabc 3
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\n",(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\n",ans); } return 0; }