HDU4821---字符串hash,map判重
这是2013年长春区域赛的铜牌题。。。然而第一次做的时候一直觉得会超时的。。最后才知道并没有想象中的那么恐怖;
这题有两个注意的地方:
(1)h[i] = h[i-1] * seed + s[i] - 'a' + 1;防止ab和aab的hash值相同;(后来感觉没必要,因为都是长度相等的串,但是长度不等的串就要注意了,所以还是写在这里吧);
(2)unsigned long long 会自动取模。所以即使乘上1e5次也不会爆orz。。这是组成原理的内容了。。我也是从别的大神那里听来的;
这到题的题意就是求有多少个连续的字子串,他由m*l个小子串组成,并且m个小子串两两互不完全相同,注意区分子串与小子串的概念;
思路是对每一个小子串赋予一个hash值,对于以ai开始的子串,如果他的小子串的hash值有m个不同值那么可以知道这个子串是符合要求的,ans++;
那么一次枚举子串的起始位置可不可以呢?可以看出肯定不行,o(n^2)的复杂度;
其实对于已经找到的一个子串,我们只需要除去他的最开头的那个小子串,加上它末尾后一个小子串,不断循环下去,就可以得到一系列的子串;
因此可以把原来的串分成l个系列,每一个系列中的子串,都是可以由第一个子串减去一个小子串,加上一个新子串得到;由此降到了o(n)的复杂度;
具体细节参考代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<map>
#define N 100005
#define lc rt<<1
#define rc rt<<1|1
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 1e5+;
const int seed = ; char s[maxn];
int m,l;
int next[maxn];
ull h[maxn];
ull base[maxn];
map<ull, int> mp; ull string_hash(int l, int r)
{
return h[r] - h[l-]*base[r-l+];//熟练掌握字符串哈希的写法,有点类似前缀和的思想;
} int main()
{
//freopen("in","r",stdin);
base[] = ;
for(int i = ; i < maxn; ++i) base[i] = base[i-]*seed;//每一位的权重;
while(~scanf("%d%d",&m,&l))
{
scanf("%s",s+);
int len = strlen(s+);
h[] = ;
for(int i = ; i <= len; ++i)
h[i] = h[i-]*seed + s[i] - 'a';//对整个字符串进行哈希; int ans = ;
for(int i = ; i <= l&&i + m*l<= len; ++i)//注意循环条件的判断
{
mp.clear();
for(int j = i; j < i + m*l ; j+=l)
{
ull x = string_hash(j,j+l-);
//printf("%lld ",x);
mp[x]++;
}
//printf("\n");
if(mp.size() == m) ans++;//mp自带去重,好用啊!
//printf("%d %d\n",i,ans);
for(int j = i + m*l; j + l- <= len; j += l)//细细体会。。。。去头添尾;
{
ull x = string_hash(j,j+l-);
mp[x]++;
ull y = string_hash(j-m*l,j-m*l+l-);
mp[y]--;
if(mp[y] == ) mp.erase(y);
if(mp.size() == m) ans++;
}
}
printf("%d\n",ans);
}
}
HDU4821---字符串hash,map判重的更多相关文章
- (通俗易懂小白入门)字符串Hash+map判重——暴力且优雅
字符串Hash 今天我们要讲解的是用于处理字符串匹配查重的一个算法,当我们处理一些问题如给出10000个字符串输出其中不同的个数,或者给一个长度100000的字符串,找出其中相同的字符串有多少个(这样 ...
- hdu 4821 字符串hash+map判重 String (长春市赛区I题)
http://acm.hdu.edu.cn/showproblem.php?pid=4821 昨晚卡了非常久,開始TLE,然后优化了之后,由于几个地方变量写混.一直狂WA.搞得我昨晚都失眠了,,. 这 ...
- POJ3087 Shuffle'm Up —— 打表找规律 / map判重
题目链接:http://poj.org/problem?id=3087 Shuffle'm Up Time Limit: 1000MS Memory Limit: 65536K Total Sub ...
- hdu 5012 bfs --- 慎用STL 比方MAP判重
http://acm.hdu.edu.cn/showproblem.php?pid=5012 发现一个问题 假设Sting s = '1'+'2'+'3'; s!="123"!!! ...
- BFS以及hash表判重的应用~
主要还是讲下hash判重的问题吧 这道题目用的是除法求余散列方式 前几天看了下算法导论 由于我们用的是线性再寻址的方式来解决冲突问题 所以hash表的大小(余数的范围)要包含我们要求的范围 对mod的 ...
- Hdu 4821 (字符串hash+map)
题目链接https://vjudge.net/problem/HDU-4821 题意:给定字符串S ,询问用几个子串满足 : 1.长度为n*len . 2. n个子串都不相同. 题解:倒序hash将 ...
- 字符串hash+回文树——hdu6599
拖了很久才补的回文树,感觉网上的博客都是一个做法..回文树统计不同种类的回文串出现次数,然后用字符串hash来判每个回文子串是否符合要求 #include<bits/stdc++.h> u ...
- 程序员的算法课(14)-Hash算法-对海量url判重
版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/m0_37609579/article/de ...
- BFS+Hash(储存,判重) HDOJ 1067 Gap
题目传送门 题意:一个图按照变成指定的图,问最少操作步数 分析:状态转移简单,主要是在图的存储以及判重问题,原来队列里装二维数组内存也可以,判重用神奇的hash技术 #include <bits ...
随机推荐
- brent ozar的sqlserver dba训练课程翻译——第二章:手动恢复数据库
备份的唯一原因 备份的唯一原因是我们可以还原 当我第一次成为sqlserver数据库管理员,只要备份工作都能成功运行,我就会觉得一切都很好.我会查看sqlserver代理,保证那些作业都在运行,然 ...
- UML[1] UML类图关系(泛化 、继承、实现、依赖、关联、聚合、组合)(转)
转自:http://blog.csdn.net/zhaoxu0312/article/details/7212152 继承.实现.依赖.关联.聚合.组合的联系与区别 分别介绍这几种关系: 继承 指的是 ...
- Java快速排序
快速排序: public int Partition(int[] nums, int low, int high) { int pivot = nums[low]; while (low < h ...
- Android-自定义PopupWindow
PopupWindow在应用中应该是随处可见的,很常用到,比如在旧版本的微信当中就用到下拉的PopupWindow,那是自定义的.新版微信5.2的ActionBar,有人已经模仿了它,但微信具体是使用 ...
- hdu2795Billboard(线段树)
http://acm.hdu.edu.cn/showproblem.php?pid=2795 单点更新,树存储的为某一行内剩余的长度 // File Name: hdu2795.cpp // Auth ...
- JDK版本错误:Unsupported major.minor version 51.0
错误原因 有时候把项目从本机编译文件部署到服务器,或者发给别人使用时,会报如下异常: java.lang.UnsupportedClassVersionError: test_hello_world ...
- Swift中实现点击、双击、捏、旋转、拖动、划动、长按手势的类和方法介绍
1.UITapGestureRecognizer 点击/双击手势 代码如下: var tapGesture = UITapGestureRecognizer(target: self, action: ...
- StringBuffer和StringBuilder使用方法比較
StringBuffer是字符串缓冲区,是一个容器. 特点: 1,长度是可变化的. 2,能够字节操作多个数据类型. 3,终于会通过toString方法变成字符串. C create U update ...
- linux/unix运行级别
在SYSTEM V 风格的UNIX系统中,系统被分为不同的运行级别,这和BSD分支的UNIX有所不同,常用的为0~6七个级别:0关机 1单用户 2不带网络的多用户 3带网络的多用户 4保留,用户可以自 ...
- pd的django To Do List教程-----3:模板的建立
---恢复内容开始--- 1:在app下建立static文件夹并且放入bootstrap文件包以及一个写好的css文件style.css.文件目录如下: style.css代码: .form-cont ...