HDU 3973 AC's String 字符串哈希
HDU 3973
通过哈希函数将一个字符串转化为一个整数,通过特定的方式可以使得这个哈希值几乎没有冲突(这就是关键之处,几乎没有视为没有= =!, 其实也可以考虑实现哈希冲突时的处理,只是这道题没必要而已),然后使用线段树维护修改后的哈希值。
因为输入的字符串只有26个,考虑使用一个大于等于26的素数p作为进制,然后将原串转化为一个p进制的数mod 2^63(也相当于自然溢出),然后这个数存入map中,然后使用线段树维护长串区间的哈希值,hash[l, r]表示将区间[l, r]的字符串转化为p进制数(哈希过程)的结果,那么对于当前区间[l, r]的两个子区间[l, m]与[m + 1, r]:
hash[l, r] = hash[l, m] + hash[m + 1, r] * (p ^ (m - l + 1))
使用线段树动态维护,查询区间的hash值,使用map查找,那么问题就解决了。
1 //#pragma comment(linker, "/STACK:1677721600") 2 #include <map> 3 #include <set> 4 #include <stack> 5 #include <queue> 6 #include <cmath> 7 #include <ctime> 8 #include <vector> 9 #include <cstdio> 10 #include <cctype> 11 #include <cstring> 12 #include <cstdlib> 13 #include <iostream> 14 #include <algorithm> 15 using namespace std; 16 #define INF 0x3f3f3f3f 17 #define inf (-((LL)1<<40)) 18 #define lson k<<1, L, (L + R)>>1 19 #define rson k<<1|1, ((L + R)>>1) + 1, R 20 #define mem0(a) memset(a,0,sizeof(a)) 21 #define mem1(a) memset(a,-1,sizeof(a)) 22 #define mem(a, b) memset(a, b, sizeof(a)) 23 #define FIN freopen("in.txt", "r", stdin) 24 #define FOUT freopen("out.txt", "w", stdout) 25 #define rep(i, a, b) for(int i = a; i <= b; i ++) 26 #define dec(i, a, b) for(int i = a; i >= b; i --) 27 28 template<class T> T MAX(T a, T b) { return a > b ? a : b; } 29 template<class T> T MIN(T a, T b) { return a < b ? a : b; } 30 template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; } 31 template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b; } 32 33 //typedef __int64 LL; 34 typedef long long LL; 35 const int MAXN = 100000 + 100; 36 const int MAXM = 110000; 37 const double eps = 1e-8; 38 LL MOD = 1000000007; 39 40 const LL P = 33; 41 42 int t, n, m, cas = 0, l, r; 43 LL mi[MAXN]; 44 char str[2000001], ch; 45 map<LL, int>mp; 46 47 void init() { 48 mi[0] = 1; 49 rep (i, 1, MAXN - 1) { 50 mi[i] = mi[i - 1] * P; 51 } 52 } 53 54 int toNum(char ch) { 55 return ch - 'a' + 1; 56 } 57 58 LL Hash() { 59 LL ans = 0; 60 int len = strlen(str); 61 dec (i, len - 1, 0) { 62 ans = ans * P + toNum(str[i]); 63 } 64 return ans; 65 } 66 67 struct SegTree { 68 LL ma[MAXN << 2]; 69 70 void update(int k, int L, int R, int p, int v) { 71 if(L == R) { ma[k] = v; return ; } 72 int mid = (L + R) >> 1; 73 if(mid >= p) update(lson, p, v); 74 else update(rson, p, v); 75 ma[k] = ma[k << 1] + ma[k << 1 | 1] * mi[mid - L + 1]; 76 } 77 78 LL query(int k, int L, int R, int l, int r) { 79 if(r < L || R < l) return 0; 80 if(l <= L && R <= r) return ma[k]; 81 LL le = query(lson, l, r), ri = query(rson, l, r); 82 int mid = (L + R) >> 1; 83 return le + ri * mi[max(mid - max(L, l) + 1, 0)]; 84 } 85 86 }st; 87 88 int main() 89 { 90 // FIN; 91 init(); 92 cin >> t; 93 while(t--) { 94 mp.clear(); 95 mem0(st.ma); 96 scanf("%d%*c", &n); 97 rep (i, 0, n - 1) { 98 scanf("%s", str); 99 mp[Hash()] = 1; 100 } 101 scanf("%s", str); 102 int len = strlen(str); 103 rep (i, 0, len - 1) { 104 st.update(1, 1, len, i + 1, toNum(str[i])); 105 } 106 printf("Case #%d:\n", ++cas); 107 scanf("%d%*c", &m); 108 while(m --) { 109 scanf("%c", &ch); 110 if(ch == 'Q') { 111 scanf("%d %d%*c", &l, &r); 112 printf("%s\n", mp[st.query(1, 1, len, ++l, ++r)] ? "Yes" : "No"); 113 } 114 else { 115 scanf("%d %c%*c", &l, &ch); 116 st.update(1, 1, len, ++l, toNum(ch)); 117 } 118 } 119 } 120 return 0; 121 }
转载于:https://www.cnblogs.com/gj-Acit/p/4678576.html
HDU 3973 AC's String 字符串哈希相关推荐
- HDU - 4821 String(字符串哈希+优化)
题目链接:点击查看 题目大意:给出一个m和l,还有一个字符串,问在s中所有长度为m*l的连续子字符串中,有多少个满足条件的子字符串 这里的满足条件指的是,长度为m*l的子字符串,可以分成m个长度为l的 ...
- HDU - 3613 Best Reward(字符串哈希)
题目链接:点击查看 题目大意:给出一个字符串,每个字母都有一个贡献值,现在要将这个字符串拆成两个子串,如果子串是回文串的话,贡献就是其中每个字母的贡献和,现在问贡献最大为多少 题目分析:很简单的一道回 ...
- hdu 6086 Rikka with String(AC自动机+状压dp)
题目链接:hdu 6086 Rikka with String 题意: 给你n个只含01的串,和一个长度L,现在让你构造出满足s[i]≠s[|s|−i+1] for all i∈[1,|s|] ,长度 ...
- String Hashing - 字符串哈希化
String Hashing - 字符串哈希化 String Hashing (字符串哈希化) 简单理解就是将一个字符串转换为一个整数.一般情况下,hash 值会比原始值更易储存 (更小) 或比较. ...
- 【牛客 -2A】矩阵(二分,字符串哈希)
题干: 给出一个n * m的矩阵.让你从中发现一个最大的正方形.使得这样子的正方形在矩阵中出现了至少两次.输出最大正方形的边长. 输入描述: 第一行两个整数n, m代表矩阵的长和宽: 接下来n行,每行 ...
- 【java学习】String字符串
1,概念 1)String 不可变 不可变类:final,不可被继承. public final class String implements java.io.Serializable, Compa ...
- 138. 兔子与兔子【字符串哈希】
很基础的字符串哈希 #include<bits/stdc++.h> using namespace std; typedef unsigned long long int ull; con ...
- Singing Superstar 字符串哈希-map操作
题意 : 给一长度 < 1e5 的字符串s,q < 1e5次询问,每次问一个长 < 30 的串 t 在s中出现的次数,且t不可重叠. 例 : "abababa"中 ...
- 中石油训练赛 - DNA(字符串哈希)
题目链接:点击查看 题目大意:给出一串只由A,C,G,T组成的字符串,再给出一个数字k,问每个长度为k的连续子串,出现的次数最多是多少次 题目分析:O(n)哈希一下,O(n)更新一下用无序map维护的 ...
最新文章
- hibernate正向生成数据库表以及配置——Student.java
- python是一种什么类型的编程语言-Python这么火,为什么说它不是未来的编程语言?...
- 《系统集成项目管理工程师》必背100个知识点-28范围管理计划和需求管理计划...
- python找指定内容_python查找指定具有相同内容文件的方法
- 无人机导航定位系统Java_无人机高精度室内定位导航的技术方案
- [hackerrank]Manasa and Stones
- POJ2104 K-th number 函数式线段树
- 送给python新手关于pip用法和虚拟环境用法的介绍(英文)
- 定义泛型集合的命名空间:System.Collections.Generic
- 猫/路由器/网关/交换机的作用与区别
- html5初学者小游戏源代码,html5 一个“一笔画”小游戏源码(通关)
- Android控件详解之网格控件
- 增强型GaN器件的驱动电路
- 5. 等可能概型(古典概型)
- linux镜像使用什么pe安装系统,Linux系统ISO镜像文件可不可以用pe启动盘来安装
- win10睡眠只是关掉显示器的问题
- -什么样的网站能赚钱
- 利用策略组限制特定软件的运行
- jquery/js实现一个网页同时调用多个倒计时(最新的)
- MFC实现浮点/进制转换计算器
热门文章
- 数据库本地服务器为空,本地搭建的服务器访问不到数据库数据
- linux的子进程和父进程,[Linux进程]在父进程和子进程中分别对文件进行操作
- 多线程的几种实现方法
- 006_Gson定制型适配器
- 004_淡入淡出效果
- linux 跑cpu负载工具,CPU负载查看工具
- java序列化的作用
- 一章: CentOS6.5 网络配置、修改主机名、添加硬盘、压缩——解压方法、VNC—server配置
- 苹果学生购机优惠_送AirPods!苹果暑季学生优惠收MacBook Air+AirPods
- 360浏览器极速模式_【小技巧】解除浏览器主页以及,锁定主页~