问题描述
有一个 10\leq10≤长度\leq 1,000,000≤1,000,000 的字符串,仅由小写字母构成。求有多少个子串,包含有至少k(1 \leq k \leq 26)k(1≤k≤26)个不同的字母?
输入描述
输入包含多组数据. 第一行有一个整数T (1\leq T\leq 10)T(1≤T≤10), 表示测试数据的组数. 对于每组数据:
第一行输入字符串SS。
第二行输入一个整数kk。
输出描述
对于每组数据,输出符合要求的子串的个数。
输入样例
2
abcabcabca
4
abcabcabcabc
3
输出样例
0
55

有一个明显的性质:如果子串(i,j)包含了至少k个不同的字符,那么子串(i,k),(j < k < length)也包含了至少k个不同字符。

因此对于每一个左边界,只要找到最小的满足条件的右边界,就能在O(1)时间内统计完所有以这个左边界开始的符合条件的子串。

寻找这个右边界,是经典的追赶法(尺取法,双指针法)问题。维护两个指针(数组下标),轮流更新左右边界,同时累加答案即可。复杂度 O(length(S))。

------------------------------------------------

就像一把尺子一样,刚开始left = right = 0,然后先固定起点 left = 0,找到满足条件的尺子长度,然后left++,修改right长度,尺子长度不变,左边一旦往后加,右边也得往后加。

 #include <iostream>
#include <algorithm>
#include <cstdio>
#include <set>
#include <cstring>
using namespace std;
typedef long long LL;
const int Max = + ;
char str[Max];
int cnt[];
int main()
{
int t;
scanf("%d", &t);
while (t--)
{
int k, left, right;
scanf("%s", str);
scanf("%d", &k);
int len = strlen(str);
int num = ;
left = right = ;
memset(cnt, , sizeof(cnt));
LL ans = ;
while (left <= len - k)
{
while (num < k && right < len) // 一直找到 满足 k 个不同字符,即尺子的右端
{
if (cnt[ str[right] - 'a'] == )
{
num++;
}// 没访问才++;
cnt[ str[right] - 'a']++;
right++;
}
if (num == k) // 当字符个数 == k的时候就可以统计子串个数了
ans += len - right + ;
cnt[ str[left] - 'a' ]--; // 左边要往后移,所以如果left位置字符个数--之后为0那么 字符个数 num也得-1
if (cnt[ str[left] - 'a'] == )
num--;
left++;
}
printf("%I64d\n", ans);
}
return ;
}

HDU5672String(尺标法)的更多相关文章

  1. [ACM_其他] 总和不小于S的连续子序列的长度的最小值——尺缩法

    Description: 给定长度为n的整数数列,A[0],A[1],A[2]….A[n-1]以及整数S,求出总和不小于S的连续子序列的长度的最小值.如果解不存在,则输出0. Input: 输入数据有 ...

  2. 初窥构建之法——记2020BUAA软工个人博客作业

    项目 内容 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任建) 这个作业的要求在哪里 个人博客作业 我在这个课程的目标是 完成一次完整的软件开发经历并以博客的方式记录开发过程的心得掌握 ...

  3. KPI:Key Performance Indicator

    通信中KPI,是Key Performance Indicators的缩写,意思是关键性能指标.performance 还有绩效:业绩的意思,但显然不适用于这种场合. 通信中KPI的内容有:掉话率.接 ...

  4. CodeForces 165C Another Problem on Strings(组合)

    A string is binary, if it consists only of characters "0" and "1". String v is a ...

  5. 模拟赛1031d1

    NP(np)Time Limit:1000ms Memory Limit:64MB题目描述LYK 喜欢研究一些比较困难的问题,比如 np 问题.这次它又遇到一个棘手的 np 问题.问题是这个样子的:有 ...

  6. 火狐的调试利器-----Firebug

    什么是Firebug 从事了数年的Web开发工作,越来越觉得现在对WEB开发有了更高的要求.要写出漂亮的HTML代码:要编写精致的CSS样式表展示每个页面模块:要调试javascript给页面增加一些 ...

  7. poj 算法 分类

    转载请注明出处:優YoU http://blog.csdn.net/lyy289065406/article/details/6642573 最近AC题:2528   更新时间:2011.09.22  ...

  8. HDOJ-三部曲一(搜索、数学)-1008-Prime Path

    Prime Path Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 131072/65536K (Java/Other) Total S ...

  9. POJ 3308 Paratroopers(最小割EK(邻接表&矩阵))

    Description It is year 2500 A.D. and there is a terrible war between the forces of the Earth and the ...

随机推荐

  1. 比较Windows Azure 网站(Web Sites), 云服务(Cloud Services)and 虚机(Virtual Machines)

    Windows Azure提供了几个部署web应用程序的方法,比如Windows Azure网站.云服务和虚拟机.你可能无法确定哪一个最适合您的需要,或者你可能清楚的概念,比如IaaS vs PaaS ...

  2. app状态监听广播

    手机中的应用在安装.更新和卸载时都会发送广播 清单文件 <?xml version="1.0" encoding="utf-8"?> <man ...

  3. background-size对background-position的影响

    CSS3中提出了background-size属性,该属性可以设置背景图片的大小,该属性的值设置为绝对数值或者百分比时对background-position没有任何影响,当设置为contain/co ...

  4. 78 mount 挂载Linux系统外的文件。

    语法 mount [-hV] mount -a [-fFnrsvw] [-t vfstype] mount [-fnrsvw] [-o options [,...]] device | dir mou ...

  5. android与网络的交互

    有三种方式: 数据下载,数据上传,数据浏览 URL中一些符号 ?分隔URL和参数 &URL中参数之间的分隔符 =URL中参数对应的值

  6. JSON与js对象序列化

    JavaScript对象表示法(JavaScript Object Notation,简称JSON)是一种轻量级的数据交换格式,它基于js字面量表示法,是js的一个子集.虽然是一个js的子集但是他与语 ...

  7. [转]使用Sencha Ext JS 6打造通用应用程序

    原文地址:http://www.uedsc.com/using-sencha-ext-js-6-to-build-universal-apps.html 在Sencha和整个Ext JS团队的支持下, ...

  8. 【BZOJ 2440】【中山市选 2011】完全平方数 莫比乌斯函数+容斥原理

    网上PoPoQQQ的课件: •题目大意:求第k个无平方因子数 •无平方因子数(Square-Free Number),即分解之后所有质因数的次数都为1的数 •首先二分答案 问题转化为求[1,x]之间有 ...

  9. python面试2

    Python语言特性 1 Python的函数参数传递 看两个例子:     1 2 3 4 5 a = 1 def fun(a):     a = 2 fun(a) print a  # 1 1 2 ...

  10. HTTP/2.0与HTTP/1.1协议区别

    超文本传输协议(英文:HyperText Transfer Protocol,缩写:HTTP)是互联网上应用最为广泛的一种网络协议.设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法.通 ...