hdu 5671 String(求有多少个子串,包含有至少k(1≤k≤26)个不同的字母)

来源:互联网 发布:华三交换机ip和mac绑定 编辑:程序博客网 时间:2024/06/03 01:39

题意:

有一个 10≤长度≤1,000,000 的字符串,仅由小写字母构成。求有多少个子串,包含有至少k(1k26)个不同的字母?


思路:

如果l,r中正好包含有k个不同的子串,那么从l开始的包含k个不同字符的串有strlen(s)-r+1

所以我们只需要计算出每个l对应的正好包含k个不同字符的r便可以了,利用双指针便可以完成。


#include <map>#include <set>#include <stack>#include <queue>#include <cmath>#include <ctime>#include <vector>#include <cstdio>#include <cctype>#include <cstring>#include <cstdlib>#include <iostream>#include <algorithm>using namespace std;#define INF 0x3f3f3f3f#define inf -0x3f3f3f3f#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define mem0(a) memset(a,0,sizeof(a))#define mem1(a) memset(a,-1,sizeof(a))#define mem(a, b) memset(a, b, sizeof(a))typedef long long ll;const int maxn=1010000;char s[maxn];int C[27],len,k;int main(){    int _;    scanf("%d",&_);    while(_--){        scanf("%s",s+1);        scanf("%d",&k);        mem0(C);        len=strlen(s+1);        int ed=0,count=0;        ll ans=0;        for(int i=1;i<=len;i++){            if(count>=k){                 C[s[i]-'a']--;                 if(C[s[i]-'a']==0)                     count--;                ans+=(len-ed+1);                continue;            }            ed++;            for(;ed<=len;ed++){                if(C[s[ed]-'a']==0)                    count++;                C[s[ed]-'a']++;                if(count>=k)                    break;            }            if(count<k||ed>len)                break;            ans+=(len-ed+1);            C[s[i]-'a']--;            if(C[s[i]-'a']==0)                count--;        }        printf("%lld\n",ans);    }    return 0;}


0 0
原创粉丝点击