HDU 5672 String 尺取法
String
题目连接:
http://acm.hdu.edu.cn/showproblem.php?pid=5672
Description
There is a string S.S only contain lower case English character.(10≤length(S)≤1,000,000)
How many substrings there are that contain at least k(1≤k≤26) distinct characters?
Input
There are multiple test cases. The first line of input contains an integer T(1≤T≤10) indicating the number of test cases. For each test case:
The first line contains string S.
The second line contains a integer k(1≤k≤26).
Output
For each test case, output the number of substrings that contain at least k dictinct characters.
Sample Input
2
abcabcabca
4
abcabcabcabc
3
Sample Output
0
55
Hint
题意
有一个 \(10\leq\)长度\(\leq 1,000,000\) 的字符串,仅由小写字母构成。求有多少个子串,包含有至少\(k(1 \leq k \leq 26)\)个不同的字母?
题解:
用一个尺取法,去维护起点为l的子串,最少应该到达哪儿
然后再统计答案就好了。
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e6+5;
char s[maxn];
int k;
int ans[maxn];
int mp[30];
void solve()
{
memset(ans,-1,sizeof(ans));
memset(mp,0,sizeof(mp));
scanf("%s",s);
scanf("%d",&k);
int num = 0;
int l = 0;
int len = strlen(s);
for(int i=0;i<len;i++)
{
mp[s[i]-'a']++;
if(mp[s[i]-'a']==1)num++;
while(num==k&&l<len)
{
ans[l]=i;
mp[s[l]-'a']--;
if(mp[s[l]-'a']==0)num--;
l++;
}
}
long long Ans = 0;
for(int i=0;i<len;i++)
{
if(ans[i]==-1)continue;
Ans+=(len-ans[i]);
}
cout<<Ans<<endl;
}
int main()
{
int t;scanf("%d",&t);
while(t--)solve();
return 0;
}