String (套路Hash)

题目链接:https://vjudge.net/contest/344930#problem/I

 

题目大意:给你一个串s,和m,l.问你有多少长度为m*l的s的子串满足该子串由m个长度为l且个不相同的子串组成的个数.问的是长度为m * l的子串的个数。

 

思路:首先预处理出所有长度为l的字串的Hash值,之后有点像滑动窗口,前面减少了一个那么后面就增加一个。这样就可以避免算法的复杂度成为O(n^2)

 

 1 #include <stdio.h>
 2 #include <algorithm>
 3 #include <iostream>
 4 #include <stdlib.h>
 5 #include <string>
 6 #include <string.h>
 7 #include <math.h>
 8 #include <vector>
 9 #include <queue>
10 #include <stack>
11 #include <map>
12 #include <set>
13 
14 
15 #define INF 0x3f3f3f3f
16 #define LL long long
17 
18 typedef unsigned long long ull;
19 const int maxn = 2e5+10;
20 
21 
22 char s[maxn];
23 ull base = 131;
24 ull p[maxn],h[maxn];
25 
26 std::map<ull,int > mp;
27 
28 ull get(int l,int r){
29     return (h[r] - h[l-1]*p[r-l+1]);
30 }
31 
32 int main() {
33     p[0] = 1;
34     for (int i=1;i<maxn;i++) {
35         p[i] = p[i-1] * base;
36     }
37     int m,l;
38     while (~scanf("%d%d",&m,&l)) {
39         scanf("%s",s+1);
40         int len = strlen(s+1);
41         int ans = 0;
42         for (int i=1;i<=len;i++) {
43             h[i] = h[i-1] * base + s[i];
44         }
45         for (int i=1;i<=l && i+m*l-1<=len;i++) {  //枚举长度
46             mp.clear();
47             for (int j=i;j<=i+m*l-1;j+=l) {  // 枚举i+m*l-1之前的长度为l的Hash
48                 ull temp = get(j,j+l-1);
49                 mp[temp]++;
50             }
51             if (mp.size() == m) {
52                 ans++;
53             }
54             for (int j=i+m*l;l+j-1<=len;j+=l) { //枚举i+m*l-1之后的长度为l的Hash
55                 ull temp = get(j-m*l,l+j-m*l-1);
56                 mp[temp]--; // 前面减少一个
57                 if (mp[temp] == 0)
58                     mp.erase(temp);
59                 temp = get(j,j+l-1); // 后面增加一个
60                 ++mp[temp];
61                 if (mp.size() == m)
62                     ans++;
63             }
64         }
65         printf("%d\n",ans);
66     }
67     return 0;
68 }

 

全部评论

相关推荐

天降大厂offer:想从事前端就放前端的技术栈,然后项目描述,还有项目做了什么内容,使用了什么技术解决了什么问题优化了什么性能。然后头像可以不要,在读也可以不要,还有bg的话就不要放课程,写哪个学校什么本科,还有绩点排名(如果高的话),然后就是技术栈写好一点,接下来就是项目(有实习就写实习,没有就到项目),项目放两个好一点的,自己包装一下,然后有参加什么竞赛放两个就好了,接下来就是靠你自己了,毕竟211还是很难容易找的,不像我们学院本
点赞 评论 收藏
分享
头像
11-03 16:48
已编辑
百度_高级研发工程师
事实是检验真理的唯一标准。&nbsp;无论我们怎么去说,去讲述,去证明,都抵不过一个offer来得实在,无论我们怎么去复现求职中的摸爬滚打、扒皮抽筋、狼狈不堪,都抵不过你在简历写上大厂的名字(外包不算)。&nbsp;所以在我求职期间,我什么话都不说,什么话都不讲,因为没有意义,虽然我总讲过程才是意义,但只有当你上岸的那一刻,你才有资格回想在水里的挣扎,只有等你出了山,你才知道山的全貌。&nbsp;我为什么一定要离开华为OD,难道它不稳定吗,不能赚钱吗。为了证明自己,那肯定有的。其实更多的是印证我的认知是否真的正确。&nbsp;(给不了解我的人交代一下背景,在下双非一本,gap一年,华为OD外包,摸爬滚打4个月,艰难上岸百度正编)一、...
先锋战士:说得很真诚。鄙视链自古有之,学历,家庭背景,财富,权利。从小有之,小学羡慕那些当班委的,中学羡慕那些学生会的,高中羡慕尖子班拿教学金的,大学羡慕高绩点,毕业了羡慕进大厂的。工作了,又羡慕高职级的,再后来又羡慕别人早早结婚的。我想表达的观点很简单,无论是华为od还是百度,都是经历,没有孰高孰低,为了抵达下一个风景,总会付出更多东西,但不就是人生吗?正如登山,每个阶段的山,都要想办法攀登,在博主的文字中,见到了坚持和积极寻找问题解决办法的心态
学历对求职的影响
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务