题意:给定一个字符串S,求S的子串个数满足子串里每个字符的个数不超过k。
方法一:维护一个起点下标pos,初始为0,如果当前为i,num[ str[ i ] ]++,如果num[ str[ i ] ]大于k,就让pos向右保证pos到i区间每个字母个
数都不超过k,然后ans+=i - pos + 1 。详见代码:
// file name: hdu5056.cpp //
// author: kereo //
// create time: 2014年09月28日 星期日 23时23分11秒 //
//***********************************//
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<stack>
#include<cmath>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
const int MAXN=100000+100;
const int inf=0x3fffffff;
const int mod=1000000000+7;
#define L(x) (x<<1)
#define R(x) (x<<1|1)
int n,k;
char str[MAXN];
int num[26];
int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%s%d",str,&k);
n=strlen(str);
memset(num,0,sizeof(num));
int pos=0; ll ans=0;
for(int i=0;i<n;i++){
int x=str[i]-'a';
num[x]++;
if(num[x]>k){
while(str[pos]!=str[i]){
num[str[pos]-'a']--;
pos++;
}
num[str[pos]-'a']--;
pos++;
}
ans+=i-pos+1;
}
printf("%I64d\n",ans);
}
}
方法二:假设当前考虑的是i,二分找到最左的pos。
// file name: hdu5056.cpp //
// author: kereo //
// create time: 2014年09月28日 星期日 23时23分11秒 //
//***********************************//
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<stack>
#include<cmath>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
const int MAXN=100000+100;
const int inf=0x3fffffff;
const int mod=1000000000+7;
#define L(x) (x<<1)
#define R(x) (x<<1|1)
int n,k;
char str[MAXN];
int num[26];
int dp[MAXN][26];
bool ok(int pos,int mid){
for(int i=0;i<26;i++){
if(dp[pos][i]-dp[mid-1][i]>k)
return false;
}
return true;
}
int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%s%d",str,&k);
n=strlen(str);
for(int i=0;i<26;i++) dp[0][i]=0;
for(int i=1;i<=n;i++){
for(int j=0;j<26;j++)
dp[i][j]=dp[i-1][j];
dp[i][str[i-1]-'a']++;
}
ll res=0;
for(int i=1;i<=n;i++){
int l=1,r=n,ans;
while(l<=r){
int mid=(l+r)>>1;
if(ok(i,mid)){
ans=mid;
r=mid-1;
}
else
l=mid+1;
}
res+=i-ans+1;
}
printf("%I64d\n",res);
}
return 0;
}