这是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)的复杂度;

具体细节参考代码:

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<algorithm>
  4. #include<cstring>
  5. #include<vector>
  6. #include<map>
  7. #define N 100005
  8. #define lc rt<<1
  9. #define rc rt<<1|1
  10. using namespace std;
  11. typedef long long ll;
  12. typedef unsigned long long ull;
  13. const int maxn = 1e5+;
  14. const int seed = ;
  15.  
  16. char s[maxn];
  17. int m,l;
  18. int next[maxn];
  19. ull h[maxn];
  20. ull base[maxn];
  21. map<ull, int> mp;
  22.  
  23. ull string_hash(int l, int r)
  24. {
  25. return h[r] - h[l-]*base[r-l+];//熟练掌握字符串哈希的写法,有点类似前缀和的思想;
  26. }
  27.  
  28. int main()
  29. {
  30. //freopen("in","r",stdin);
  31. base[] = ;
  32. for(int i = ; i < maxn; ++i) base[i] = base[i-]*seed;//每一位的权重;
  33. while(~scanf("%d%d",&m,&l))
  34. {
  35. scanf("%s",s+);
  36. int len = strlen(s+);
  37. h[] = ;
  38. for(int i = ; i <= len; ++i)
  39. h[i] = h[i-]*seed + s[i] - 'a';//对整个字符串进行哈希;
  40.  
  41. int ans = ;
  42. for(int i = ; i <= l&&i + m*l<= len; ++i)//注意循环条件的判断
  43. {
  44. mp.clear();
  45. for(int j = i; j < i + m*l ; j+=l)
  46. {
  47. ull x = string_hash(j,j+l-);
  48. //printf("%lld ",x);
  49. mp[x]++;
  50. }
  51. //printf("\n");
  52. if(mp.size() == m) ans++;//mp自带去重,好用啊!
  53. //printf("%d %d\n",i,ans);
  54. for(int j = i + m*l; j + l- <= len; j += l)//细细体会。。。。去头添尾;
  55. {
  56. ull x = string_hash(j,j+l-);
  57. mp[x]++;
  58. ull y = string_hash(j-m*l,j-m*l+l-);
  59. mp[y]--;
  60. if(mp[y] == ) mp.erase(y);
  61. if(mp.size() == m) ans++;
  62. }
  63. }
  64. printf("%d\n",ans);
  65. }
  66. }

HDU4821---字符串hash,map判重的更多相关文章

  1. (通俗易懂小白入门)字符串Hash+map判重——暴力且优雅

    字符串Hash 今天我们要讲解的是用于处理字符串匹配查重的一个算法,当我们处理一些问题如给出10000个字符串输出其中不同的个数,或者给一个长度100000的字符串,找出其中相同的字符串有多少个(这样 ...

  2. hdu 4821 字符串hash+map判重 String (长春市赛区I题)

    http://acm.hdu.edu.cn/showproblem.php?pid=4821 昨晚卡了非常久,開始TLE,然后优化了之后,由于几个地方变量写混.一直狂WA.搞得我昨晚都失眠了,,. 这 ...

  3. POJ3087 Shuffle'm Up —— 打表找规律 / map判重

    题目链接:http://poj.org/problem?id=3087 Shuffle'm Up Time Limit: 1000MS   Memory Limit: 65536K Total Sub ...

  4. hdu 5012 bfs --- 慎用STL 比方MAP判重

    http://acm.hdu.edu.cn/showproblem.php?pid=5012 发现一个问题 假设Sting s = '1'+'2'+'3'; s!="123"!!! ...

  5. BFS以及hash表判重的应用~

    主要还是讲下hash判重的问题吧 这道题目用的是除法求余散列方式 前几天看了下算法导论 由于我们用的是线性再寻址的方式来解决冲突问题 所以hash表的大小(余数的范围)要包含我们要求的范围 对mod的 ...

  6. Hdu 4821 (字符串hash+map)

    题目链接https://vjudge.net/problem/HDU-4821 题意:给定字符串S ,询问用几个子串满足 : 1.长度为n*len  . 2. n个子串都不相同. 题解:倒序hash将 ...

  7. 字符串hash+回文树——hdu6599

    拖了很久才补的回文树,感觉网上的博客都是一个做法..回文树统计不同种类的回文串出现次数,然后用字符串hash来判每个回文子串是否符合要求 #include<bits/stdc++.h> u ...

  8. 程序员的算法课(14)-Hash算法-对海量url判重

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/m0_37609579/article/de ...

  9. BFS+Hash(储存,判重) HDOJ 1067 Gap

    题目传送门 题意:一个图按照变成指定的图,问最少操作步数 分析:状态转移简单,主要是在图的存储以及判重问题,原来队列里装二维数组内存也可以,判重用神奇的hash技术 #include <bits ...

随机推荐

  1. 中介者模式(Mediator) 笔记

    中介者模式(Mediator Pattern):定义一个中介对象来封装系列对象之间的交互.中介者使各个对象不需要显示地相互引用,从而使其耦合性松散,而且可以独立地改变他们之间的交互. 类图: Medi ...

  2. (转)iOS分类和扩展(Categories和Extensions)

    分类(Category)   分类能够做到的事情主要是:即使在你不知道一个类的源码情况下,向这个类添加扩展的方法.   此外,分类能够保证你的实现类和其他的文件区分开. #import “UIView ...

  3. @property属性关键字

    关于@property属性关键字使用注意:* weak(assign) :  代理\UI控件* strong(retain) : 其他对象(除代理\UI控件\字符串以外的对象)* copy : 字符串 ...

  4. 控制uibutton的title范围

    moreBtn.contentEdgeInsets = UIEdgeInsetsMake(0,10, 0, 10);

  5. Eclipse 4.2 + Tomcat 7.x + JDK 7 搭建Java Web开发环境

    1. 准备工具 Eclipse 4.2 (到官网下载:http://www.eclipse.org/downloads/  要下载Eclipse IDE for Java EE Developers ...

  6. iOS-BLE蓝牙开发持续更新

    文/煜寒了(简书作者)原文链接:http://www.jianshu.com/p/84b5b834b942著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”. 在写这个博客之前,空余时间抽看 ...

  7. 数据持久化之CoreData

    再次回归博客园, 已经实属不易了, 面临这近期忙忙碌碌的项目开发, 虽然并不是完全的没有闲暇时间, 但是怎么说呢, 也有着各种的无奈与曲折, 面临这产品需求的不断变化和页面的不断更新, 对于一个程序员 ...

  8. springmvc中项目启动直接调用方法

    1. <servlet> <servlet-name> AutoServlet </servlet-name> <servlet-class> com. ...

  9. NS2仿真:两个移动节点网络连接及协议性能分析

    NS2仿真实验报告2 实验名称:两个移动节点网络连接及协议性能分析 实验日期:2015年3月9日~2015年3月14日 实验报告日期:2015年3月15日 一.实验环境(网络平台,操作系统,网络拓扑图 ...

  10. OD: Shellcode / Exploit & DLL Trampolining

    看到第五章了. 标题中 Dll Tramplining(跳板)名字是从如下地址找到的,写的很好: http://en.wikipedia.org/wiki/Buffer_overflow#The_ju ...