HDU 5056 Boring count(BestCoder Round #11 (Div. 2))

Problem Description:

You are given a string S consisting of lowercase letters, and your task is counting the number of substring that the number of each lowercase letter in the substring is no more than K.

Input:

In the first line there is an integer T , indicates the number of test cases.
For each case, the first line contains a string which only consist of lowercase letters. The second line contains an integer K.

[Technical Specification]
1<=T<= 100
1 <= the length of S <= 100000
1 <= K <= 100000

Output:

For each case, output a line contains the answer.

Sample Input:

3

abc

1

abcabc

1

abcabc

2

Sample Output:

6

15

21

题意:给出一个字符串s和一个整数k,问有多少s的子串满足条件,条件是子串中每个字母出现的个数不能大于k(只有小写字母)。

这里用到一个公式,一个长度为n的字符串的连续子串的个数为1+2+3+……+n。证明:举例如abcabc:我们可以分别得到该字符串长度为1,2,3,4,5,6的子串:

1:a     b     c     a     b     c;

2:ab     bc     ca     ab     bc;

3:abc     bca     cab     abc;

4:abca      bcab     cabc;

5:abcab     bcabc;

6:abcabc;

不难发现连续子串的个数和是1+2+3+……+n。

#include<stdio.h>
#include<string.h>
#include<queue>
#include<math.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;

const int N=1e5+10;
const int INF=0x3f3f3f3f;
const int MOD=1e9+7;

typedef long long LL;

char s[N];
int vis[N]; ///标记序号为i的字母出现的次数

int main ()
{
    int T, k, i, j;
    LL ans; ///这里必须用LL,不然会wa

    scanf("%d", &T);

    while (T--)
    {
        scanf("%s %d", s, &k);

        j = 0; ///当发现一个字母出现的次数>k时,j的值会改变
        ans = 0;
        memset(vis, 0, sizeof(vis));

        for (i = 0; s[i] != ‘\0‘; i++)
        {
            vis[s[i]-‘a‘]++;

            if (vis[s[i]-‘a‘] > k)
            {
                while (s[j] != s[i]) ///举例:bcaacb(k==1),当我们找到第二个a时发现a出现的次数大于k了,首先之前的bca已经算出了子串个数1+2+3,所以现在的bc的次数需要减1,j需要移到前一个a
                {
                    vis[s[j]-‘a‘]--;
                    j++;
                }

                vis[s[i]-‘a‘]--; ///还是上面的例子由于现在a的次数大于k,那么我们也需要将a的次数减1,j指向现在的a(当然举例:abcabc也是成功的,只是这时没有经过while循环那一步)
                j++;
            }

            ans += i-j+1; ///这里计算子串的个数,至于为什么只加上字符的个数,举例:abc:在a的时候我们会加1(可以看做加上了a这个子串),在b的时候加2(本来ab有三个子串:a,b,ab,但是之前加了a,不能重复,所以加2),那么在c的时候同理加3就好了
        }

        printf("%lld\n", ans);
    }

    return 0;
}
时间: 2024-11-08 22:14:19

HDU 5056 Boring count(BestCoder Round #11 (Div. 2))的相关文章

HDU 5056 Boring count(数学)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5056 Problem Description You are given a string S consisting of lowercase letters, and your task is counting the number of substring that the number of each lowercase letter in the substring is no more t

(BestCoder Round #64 (div.2))Array -- BestCoder Round #64 (div.2)

BestCoder Round #64 (div.2) Array 问题描述 Vicky是个热爱数学的魔法师,拥有复制创造的能力. 一开始他拥有一个数列{1}.每过一天,他将他当天的数列复制一遍,放在数列尾,并在两个数列间用0隔开.Vicky想做些改变,于是他将当天新产生的所有数字(包括0)全加1.Vicky现在想考考你,经过100天后,这个数列的前M项和是多少?. 输入描述 输入有多组数据. 第一行包含一个整数T,表示数据组数.T. \left( 1 \leq T \leq 2 * {10}^

hdu Boring count(BestCode round #11)

Boring count Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 360    Accepted Submission(s): 140 Problem Description You are given a string S consisting of lowercase letters, and your task is co

hdu 5056 Boring count (类似单调队列的做法。。)

给一个由小写字母构成的字符串S,问有多少个子串满足:在这个子串中每个字母的个数都不超过K. 数据范围: 1<=T<= 1001 <= the length of S <= 1000001 <= K <= 100000 思路: 考虑以S[i]结尾的子串,若以S[j] (j<i)作为头不能构成一个符合条件的子串,则S[1]...S[j]都不能作为子串的头. 若S[j+1]可以作为子串的头,则以S[i]结尾的符合条件的子串个数是i-j. 做法:单调队列的思想,不多解释,

BestCoder Round #11 (Div. 2) 前三题题解

题目链接: huangjing hdu5054 Alice and Bob 思路: 就是(x,y)在两个參考系中的表示演全然一样.那么仅仅可能在这个矩形的中点.. 题目: Alice and Bob Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 216    Accepted Submission(s): 166 Problem De

BestCoder Round #11 (Div. 2) 题解

HDOJ5054 Alice and Bob Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 302    Accepted Submission(s): 229 Problem Description Bob and Alice got separated in the Square, they agreed that if they

BestCoder Round #11 (Div. 2)题解集合

Alice and Bob Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 155    Accepted Submission(s): 110 Problem Description Bob and Alice got separated in the Square, they agreed that if they get sepa

hdu4931 Happy Three Friends(BestCoder Round#4签到题)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4931 Happy Three Friends Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 150    Accepted Submission(s): 128 Problem Description Dong-hao , Grandpa

CodeForces 360E Levko and Game(Codeforces Round #210 (Div. 1))

题意:有一些无向边m条权值是给定的k条权值在[l,r]区间可以由你来定,一个点s1 出发一个从s2出发  问s1 出发的能不能先打到f 思路:最短路. 首先检测能不能赢 在更新的时候  如果对于一条边 a->b  如果dis1[a] <dis2[a]  那么选择这条边就选择   l  因为这条边对于s1有利 如果两个起点都选择了这条边  则说明s1 赢定了,所以要让他们尽量走这条,所以边权越小越好.跑完之后检测 如果  dis1[f]<dis2[f] 那么 就赢了. 接下来判断能不能平局