String HDU - 4821(哈希)
String
题意:求长串中存在多少个长度为M*L的子串(是由M个长度为L的子串构成的)
算是第一道哈希题了,看的别人的代码
先求出原串左边起到第i位的哈希值h[i],然后枚举起点,计算出前M段,然后利用滑动窗口右移,因此起点只需从1枚举到L即可
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define ull unsigned long long 4 const int maxn=100010; 5 const int seed=31; 6 7 char s[maxn]; 8 int M,L; 9 ull h[maxn],base[maxn]; 10 map<ull,int> mp; 11 ull _hash(int l,int r) //求区间l到r的哈希值 12 { 13 return h[r]-h[l-1]*base[r-l+1]; 14 } 15 16 int main() 17 { 18 base[0]=1; 19 for(int i=1;i<maxn;i++) 20 base[i]=base[i-1]*seed; 21 while(scanf("%d%d",&M,&L)!=EOF){ 22 scanf("%s",s+1); 23 int len=strlen(s+1); 24 for(int i=1;i<=len;i++) 25 h[i]=h[i-1]*seed+s[i]-'a'; 26 int ans=0; 27 for(int i=1;i<=L&&i+M*L<=len;i++){ 28 mp.clear(); 29 for(int j=i;j<i+M*L;j+=L){ 30 ull x=_hash(j,j+L-1); 31 mp[x]++; 32 } 33 if(mp.size()==M)ans++; 34 //下面相当于为M段的滑动窗口,每次右移判断是否满足 35 for(int j=i+M*L;j+L-1<=len;j+=L){ 36 ull x=_hash(j,j+L-1); 37 mp[x]++; //右边进来 38 ull y=_hash(j-M*L,j-M*L+L-1); 39 mp[y]--; //左边出去 40 if(mp[y]==0) mp.erase(y); 41 if(mp.size()==M) ans++; 42 } 43 } 44 printf("%d\n",ans); 45 } 46 47 }
分类:
*字符串---哈希
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET 9 new features-C#13新的锁类型和语义
· Linux系统下SQL Server数据库镜像配置全流程详解
· 现代计算机视觉入门之:什么是视频
· 你所不知道的 C/C++ 宏知识
· 聊一聊 操作系统蓝屏 c0000102 的故障分析
· 不到万不得已,千万不要去外包
· C# WebAPI 插件热插拔(持续更新中)
· .NET 9 new features-C#13新的锁类型和语义
· 会议真的有必要吗?我们产品开发9年了,但从来没开过会
· 《SpringBoot》EasyExcel实现百万数据的导入导出