HDU 4821 字符串hash

题目大意:

希望找到连续的长为m*l的子串,使得m个l长的子串每一个都不一样,问能找到多少个这样的子串

简单的字符串hash,提前预处理出每一个长度为l的字符串的hash值

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 #include <map>
 6 #include <set>
 7
 8 using namespace std;
 9 #define N 100010
10 #define base 31
11 typedef unsigned long long ULL;
12 map<ULL , int> _map;
13 int m , l;
14 ULL fac[N] , val[N];
15 char str[N];
16
17 void init()
18 {
19     fac[0] = 1;
20     for(int i=1 ; i<=100000 ; i++) fac[i] = fac[i-1]*base;
21 }
22
23 int main()
24 {
25     #ifndef ONLINE_JUDGE
26         freopen("a.in" , "r" , stdin);
27     #endif // ONLINE_JUDGE
28     init();
29     while(~scanf("%d%d" , &m , &l))
30     {
31         scanf("%s" , str);
32         int len = strlen(str) , cnt , same , ret;
33         ULL cur = 0;
34         for(int i=0 ; i<len ; i++){
35             if(i>=l) cur = cur-fac[l-1]*str[i-l];
36             cur=cur*base+str[i];
37             if(i>=l-1) val[i-l+1] = cur;
38             //cout<<i-l+1<<" "<<val[i-l+1]<<endl;
39         }
40         ret=0;
41         for(int i=0 ; i<l ; i++){
42             _map.clear();
43             cnt = 0 , same = 0;
44             for(int j=i ; j<len ; j+=l){
45                 if(j+l-1>=len) break;
46                 if(cnt >= m){
47                     int la = j-m*l;
48                     int t = _map[val[la]]--;
49                     if(t==2) same--;
50                 }
51                 int t = _map[val[j]]++;
52                 if(t==1) same++;
53                 cnt++;
54                // cout<<j<<" "<<cnt<<" "<<endl;
55                 if(cnt >= m && same==0){
56                     ret++;
57                  //   cout<<j<<endl;
58                 }
59
60             }
61         }
62         printf("%d\n" , ret);
63     }
64     return 0;
65 }
时间: 2024-12-10 19:00:02

HDU 4821 字符串hash的相关文章

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

http://acm.hdu.edu.cn/showproblem.php?pid=4821 昨晚卡了非常久,開始TLE,然后优化了之后,由于几个地方变量写混.一直狂WA.搞得我昨晚都失眠了,,. 这几次hash军写错的变量--tmp=(j==m-1)?ah[j]:(ah[j]-ah[j-m]*base[m]);  外层循环变量是i,我写的字符串hash的几题都写成tmp=(i==0)? ah[j]:(ah[j]-ah[j-m]*base[m]); 二逼啊 题目大意: 给定一个字符串(最长10^

HDU 4821 (hash)

这道题最重要的不仅是hash这种算法,更要学会利用好STL中的<map>才行. 将连续的L个字符经过hash赋值,最后线性判断.其中的判断步骤用到了map的插入特性. #include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <map> using namespace std; #define maxn 500010 #

hdu 3973 字符串hash+线段树

http://acm.hdu.edu.cn/showproblem.php?pid=3973 Problem Description You are given some words {Wi}. Then our stupid AC will give you a very long string S. AC is stupid and always wants to know whether one substring from S exists in the given words {Wi}

2013 Asia Regional Changchun I 题,HDU(4821),Hash

题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=4821 解题报告:搞了很久,总算搞出来了,还是参考了一下网上的解法,的确很巧,和上次湘潭的比赛中的一个求平方和的题目思路很类似. 首先说一下hash,简单来说就是y = hash(x),有很多函数,可以参考这里:https://www.byvoid.com/blog/string-hash-compare/ 然后,我用的是这个:写法简单,而且重复的可能较小. // BKDR Hash Fu

hdu 1880 字符串hash

/*普通的hsah 由于元素太多 空间很小..hash碰撞很厉害.30分*/ #include<iostream> #include<cstdio> #include<cstring> #include<map> #define maxn 100010 #define mod 2000007 #define hs 117 using namespace std; int n,l,k,cnt,f[mod+10],l1[maxn],l2[maxn]; char

hdu 4821 String(字符串hash)

题目链接:hdu 4821 String 题意: 给你一个字符串,问你有多少子串,满足长度为m*len,并且这个子串能分成m个len长度的不同串. 题解: BKDRhash+map来判重.注意的是要以len长分类来扫,这样才不会超时. 1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=a;i<=b;++i) 3 using namespace std; 4 typedef unsigned long long ull; 5 co

[字符串hash] hdu 4821 String

题意: 给你M,L,再给一个串str 任意截取M*L长度的连续子串 再把这个子串分成M份长度为L的连续串 使得这M份互不相同 问有几种截取方法 思路: 考虑到子串是否相等,就运用字符串hash 用到map判重和割补的办法优化 代码: #include"cstdlib" #include"cstdio" #include"cstring" #include"cmath" #include"queue" #in

HDU 4821 杭州现场赛:每个片段字符串哈希比较

I - String Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 4821 Description Given a string S and two integers L and M, we consider a substring of S as "recoverable" if and only if (i) I

hdu 1880 魔咒词典(字符串hash)

题目链接:hdu 1880 魔咒词典 题意: 给你一个10w的词典,让你输出对应的字段. 题解: map暴力存字符串肯定会卡内存,这里用BKDR字符串hash一下,用map映射一下. 1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=a;i<=b;++i) 3 using namespace std; 4 typedef unsigned long long ull; 5 6 const int N=1e5+7,seed=133