博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HDU 4821 String 字符串哈希
阅读量:5460 次
发布时间:2019-06-15

本文共 1495 字,大约阅读时间需要 4 分钟。

题意:

给一个字符串\(s\),统计长为\(M*L\)的字串的个数。如果将该字串看成\(M\)个长为\(L\)的串拼接起来,那么这\(M\)个串必须互不相同。

分析:

枚举串的开头,然后用map来维护这\(M\)个hash值。

我用的《训练指南》上的hash方法:
定义一个\(H(n)=\sum{s_i x^{i-n}}\)
\(i\)开头的长为\(L\)的字串的hash值为:\(H(i)-H(i+L)x^L\)
hash值为unsigned long long类型,这样就不用在代码中取模了。

#include 
#include
#include
#include
using namespace std;const int maxl = 100000 + 10;char s[maxl];int n, M, L;const int x = 123;unsigned long long H[maxl], xp[maxl];map
cnt;unsigned long long hashcode(int s, int L) { return H[s] - H[s+L] * xp[L];}int main() { xp[0] = 1; for(int i = 1; i < maxl; i++) xp[i] = xp[i-1] * x; while(scanf("%d%d", &M, &L) == 2) { scanf("%s", s); n = strlen(s); H[n] = 0; for(int i = n - 1; i >= 0; i--) H[i] = H[i+1] * x + s[i] - 'a'; long long ans = 0; for(int s = 0; s + M * L <= n && s < L; s++) { cnt.clear(); for(int i = s; i < s + L * M; i += L) cnt[hashcode(i, L)]++; if(cnt.size() == M) ans++; for(int i = s + L * M; i + L <= n; i += L) { int head = i - L * M; unsigned long long p = hashcode(head, L); if(cnt[p] == 1) cnt.erase(p); else cnt[p]--; cnt[hashcode(i, L)]++; if(cnt.size() == M) ans++; } } printf("%lld\n", ans); } return 0;}

转载于:https://www.cnblogs.com/AOQNRMGYXLMV/p/4919367.html

你可能感兴趣的文章
第五章 循环结构反思
查看>>
WebConfig配置文件有哪些不为人知的秘密?
查看>>
自动控制原理的三不管地带之——开闭环函数特征方程原理
查看>>
HDU 2001 计算亮点间的距离
查看>>
spring学习笔记--quartz和定时任务执行
查看>>
ASP.NET页面刷新样式改变解决方法
查看>>
Redis- 简单操作命令
查看>>
洛谷 P2827 蚯蚓 解题报告
查看>>
考核题 6
查看>>
hadoop Datanode多目录配置
查看>>
一段获取windows环境变量的代码
查看>>
test
查看>>
MKReverseGeocoder 过时,IOS5中使用CLGeocoder
查看>>
@DataProvider Method 参数传递
查看>>
The Tao to Excellent 2
查看>>
Redis 命令
查看>>
Cocos2d-js 3.0 颜色变换(调整sprite/图片的色调)
查看>>
织梦仿站第一课
查看>>
java step1:基础知识3
查看>>
Hadoop 发行版本 Hortonworks 安装详解(二) 安装Ambari
查看>>