String

Given a string S and two integers L and M, we consider a substring of S as “recoverable” if and only if 
  (i) It is of length M*L; 
  (ii) It can be constructed by concatenating M “diversified” substrings of S, where each of these substrings has length L; two strings are considered as “diversified” if they don’t have the same character for every position.

Two substrings of S are considered as “different” if they are cut from different part of S. For example, string "aa" has 3 different substrings "aa", "a" and "a".

Your task is to calculate the number of different “recoverable” substrings of S.

InputThe input contains multiple test cases, proceeding to the End of File.

The first line of each test case has two space-separated integers M and L.

The second ine of each test case has a string S, which consists of only lowercase letters.

The length of S is not larger than 10^5, and 1 ≤ M * L ≤ the length of S.OutputFor each test case, output the answer in a single line.Sample Input

3 3
abcabcbcaabc

Sample Output

2

13年长春赛的一道题目,涉及的知识点非常多。

1.枚举出字符串中固定长度的子串,暴力做法O(n^2),这里用到了窗口移动。
即以第一个循环节中每个字符为起点,依次向后寻找直到末尾,避免了重复查询。
2.map也可以作为set使用,并且还可记录重复元素的个数。
3.hash优化。利用字符串映射效率较低,这里可以将字符串转化为数字。
将字符看作高进制数,使用unsign long long进行存储(利用了其自动取模的效果),
种子seed设为质数可以使重复的概率降到最低(可忽略不计)。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll; string s;
map<string,int> mp; int main()
{
int m,l,i,j;
while(~scanf("%d%d",&m,&l)){
cin>>s;
int len=s.length();
if(m==){
printf("%d\n",len-l+);
continue;
}
ll ans=;
for(i=;i<l;i++){
int x=;
mp.clear();
for(j=i;j+l-<len;j+=l){
x++;
mp[s.substr(j,l)]++;
if(x==m){
if(mp.size()==m) ans++;
}
else if(x>m){
x--;
if(mp[s.substr(j-m*l,l)]==){
mp.erase(s.substr(j-m*l,l));
}
else{
mp[s.substr(j-m*l,l)]--;
}
if(mp.size()==m) ans++;
}
}
}
printf("%I64d\n",ans);
}
return ;
}

优化前(920ms)

#include<bits/stdc++.h>
#define MAX 100005
#define seed 31
#define get(a,b) haxi[a]-haxi[a+b]*base[b]
using namespace std;
typedef long long ll;
typedef unsigned long long ull; string s;
map<ull,int> mp;
ull base[MAX];
ull haxi[MAX]; void init(int len){
haxi[len]=;
for(int i=len-;i>=;i--){
haxi[i]=haxi[i+]*seed+s[i]-'a';
}
}
int main()
{
int m,l,i,j;
base[]=;
for(int i=;i<=;i++){
base[i]=base[i-]*seed;
}
while(~scanf("%d%d",&m,&l)){
cin>>s;
int len=s.length();
if(m==){
printf("%d\n",len-l+);
continue;
}
init(len);
ll ans=;
for(i=;i<l;i++){
int x=;
mp.clear();
for(j=i;j+l-<len;j+=l){
x++;
mp[get(j,l)]++;
if(x==m){
if(mp.size()==m) ans++;
}
else if(x>m){
x--;
if(mp[get(j-m*l,l)]==){
mp.erase(get(j-m*l,l));
}
else{
mp[get(j-m*l,l)]--;
}
if(mp.size()==m) ans++;
}
}
}
printf("%I64d\n",ans);
}
return ;
}

优化后(327ms)

 

HDU - 4821 String(窗口移动+map去重+hash优化)的更多相关文章

  1. HDU 4821 String (HASH)

    题意:给你一串字符串s,再给你两个数字m l,问你s中可以分出多少个长度为m*l的子串,并且子串分成m个长度为l的串每个都不完全相同 首先使用BKDRHash方法把每个长度为l的子串预处理成一个数字, ...

  2. HDU 4821 String hash

    String Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/contest/view.action ...

  3. HDU 4821 String 字符串hash

    String Problem Description   Given a string S and two integers L and M, we consider a substring of S ...

  4. HDU 4821 String(BKDRHash)

    http://acm.hdu.edu.cn/showproblem.php?pid=4821 题意:给出一个字符串,现在问你可以找出多少个长度为M*L的子串,该子串被分成L个段,并且每个段的字符串都是 ...

  5. HDU 4821 String(2013长春现场赛I题)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4821 字符串题. 现场使用字符串HASH乱搞的. 枚举开头! #include <stdio.h ...

  6. [HDU 4821] String (字符串哈希)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4821 题目大意:给你M,L两个字母,问你给定字串里不含M个长度为L的两两相同的子串有多少个? 哈希+枚 ...

  7. HDU 1113 Word Amalgamation (map 容器 + string容器)

    http://acm.hdu.edu.cn/showproblem.php?pid=1113 Problem Description In millions of newspapers across ...

  8. HDU 4821 2013长春现场赛hash

    题意: 一个字符串S  问其中有几个子串能满足以下条件: 1.长度为M*L 2.可以被分成M个L长的小串  每个串都不一样 分析: hash方法,一个种子base,打表出nbase[i]表示base的 ...

  9. STL之map应用 +hash表(51nod 1095)

    题目:Anigram单词 题意:给出词典,再给出一些单词,求单词的Anigram数量. 思路:先将字串转换成哈希表,然后再用map链接. hash表构造方法汇总:http://www.cnblogs. ...

随机推荐

  1. Python 进程、线程、协程、锁机制,你知多少?

    1.python的多线程到底有没有用? 2. 为什么在python里推荐使用多进程而不是多线程 3.进程.线程.协程.各种锁 4.Python多进程编程

  2. going

  3. 我的Android进阶之旅------>报 error: Apostrophe not preceded by \ 的错误解决办法

    今天对项目进行国际化翻译的时候控制台出现了以下的错误: res/values/strings.xml:100: error: Apostrophe not preceded by \ (in Sorr ...

  4. jquery.dataTables.min.js: Uncaught TypeError: Cannot read property 'style' of undefined

    原因:datatable表格内容有操作列,而表头没有定义操作列 少写了一行:<th>操作</th>

  5. LightOJ 1132 Summing up Powers:矩阵快速幂 + 二项式定理

    题目链接:http://lightoj.com/volume_showproblem.php?problem=1132 题意: 给定n.k,求(1K + 2K + 3K + ... + NK) % 2 ...

  6. 高效上网教程---资源软件搜索技巧(搜索好用软件或者app去哪些网站)

    高效上网教程---资源软件搜索技巧(搜索好用软件或者app去哪些网站) 一.总结 一句话总结:查看下面这些网站用户推荐的 知乎:比如 小众软件 site:zhihu.com 简书:查看你需要的用户推荐 ...

  7. linux应用之tomcat安装(centos)

    安装方式:源码安装 软件:apache-tomcat-7.0.29.tar.gz下载地址:http://tomcat.apache.org/download-70.cgi 安装前提 系统必须已经安装配 ...

  8. 改变Ecplise项目窗口字体样式

    Eclipse\plugins\org.eclipse.ui.themes_1.1.1.v20151026-1355\css e4-dark_win.css CTabFolder Tree, CTab ...

  9. 跨线程send message

    今天同事问了一个问题,说在线程中send message 和直接调用是不是一样,他觉得是一样的,但是线程跟踪却发现处理过程是在接收消息队列完成.回家看到博客园上的一番争论才有些明白,这里贴出来,共勉 ...

  10. python 生成特定间隔数列的方法

    (1)range() 和 xrange( )[python内置函数] range(开始,结束,间隔). 值得注意的是:生成数列最后一个数< 结束值. 返回结果类型:list,其中元素是integ ...