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;
}
posted @ 2016-04-24 15:45  qscqesze  阅读(347)  评论(0编辑  收藏  举报