HDU3973 线段树 + 字符哈希
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3973 , 线段树 + 字符哈希,好题。
又学了一种新的哈希方法,hhhh~
解法:
想法是用P进制的数来表示一个字符串,由于可能数太大,所以就将转换成是十进制后的数模long long的最大值,这样虽然也有可能冲突,但是概率会非常小。这里的P可以随意取一个素数(我取的是31)。
先用上面提到的哈希方法将W集合中的字符串都转成十进制数存在数组中,然后进行排序;每一次询问时候,将询问区间的子串转成十进制后二分查找是否在W集合中即可。
思路虽然简单,但是实现起来还是比较麻烦,尤其是有很多细节需要注意。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <queue>
#include <vector>
#include <string>
#include <string.h>
#include <algorithm>
using namespace std;
#define LL __int64
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
const int maxn = + ;
const int p = ;
char str[];
LL Hash[maxn << ] , P[maxn];
LL W[ + ];
void init()
{
P[] = ;
for(int i = ; i <= maxn ; i++)
P[i] = P[i - ] * p;
}
LL calhash(char str[])
{
LL sum = ;
for(int i = ; str[i] != '\0' ; i++) {
sum = sum * p + str[i] - 'a' + ;
}
return sum;
}
int binary_search(int l , int r , LL a[] , LL x)
{
int m = (l + r) >> ;
while(l <= r) {
if(a[m] == x)
return m;
if(a[m] > x)
r = m - ;
if(a[m] < x)
l = m + ;
m = (l + r) >> ;
}
return -;
}
void PushUp(int l , int r , int rt)
{
int m = (l + r) >> ;
Hash[rt] = Hash[rt << ] * P[r - m] + Hash[rt << | ];
}
void build(int l , int r , int rt)
{
if(l == r) {
Hash[rt] = str[r] - 'a' + ;
return;
}
int m = (l + r) >> ;
build(lson);
build(rson);
PushUp(l , r , rt);
}
void update(int x , int l , int r , int rt)
{
if(l == r) {
Hash[rt] = str[x] - 'a' + ;
return;
}
int m = (l + r) >> ;
if(x > m)
update(x , rson);
else
update(x , lson);
PushUp(l , r , rt);
}
LL query(int L , int R , int l , int r , int rt)
{
if(L <= l && R >= r) {
return Hash[rt];
}
int m = (l + r) >> ;
if(m < L)
return query(L , R , rson);
else if(m >= R)
return query(L , R , lson);
else
return query(L , m , lson) * P[R - m] + query(m + , R , rson);
}
int main()
{
int n , m , T;
char ch[] , s[];
init();
cin >> T;
for(int k = ; k <= T ; k++)
{
scanf("%d" , &n);
for(int i = ; i <= n ; i++) {
scanf("%s" , str);
W[i] = calhash(str);
}
sort(W + , W + n + );
scanf("%s" , str);
int len = strlen(str);
build( , len - , );
printf("Case #%d:\n" , k);
scanf("%d" , &m);
while(m--) {
scanf("%s" , ch);
if(ch[] == 'Q') {
int L , R;
scanf("%d %d" , &L , &R);
LL tmp = query(L , R , , len - , );
if(binary_search( , n , W , tmp) != -)
puts("Yes");
else
puts("No");
} else {
int x;
scanf("%d" , &x);
scanf("%s" , s);
str[x] = s[];
update(x , , len - , );
}
}
}
return ;
}
HDU3973 线段树 + 字符哈希的更多相关文章
- 【URAL 1989】 Subpalindromes(线段树维护哈希)
Description You have a string and queries of two types: replace i'th character of the string by char ...
- CF213E Two Permutations 线段树维护哈希值
当初竟然看成子串了$qwq$,不过老师的$ppt$也错了$qwq$ 由于子序列一定是的排列,所以考虑插入$1$到$m$到$n-m+1$到$n$; 如何判断呢?可以用哈希$qwq$: 我们用线段树维护哈 ...
- [bzoj2124]等差子序列——线段树+字符串哈希
题目大意 给一个1到N的排列\(A_i\),询问是否存在\(p_i\),\(i>=3\),使得\(A_{p_1}, A_{p_2}, ... ,A_{p_len}\)是一个等差序列. 题解 显然 ...
- 51Nod1553 周期串查询 字符串 哈希 线段树
原文链接https://www.cnblogs.com/zhouzhendong/p/51Nod1553.html 题目传送门 - 51Nod1553 题意 有一个串只包含数字字符.串的长度为n,下标 ...
- 线段树+哈希【CF580E】Kefa and Watch
线段树+哈希[CF580E]Kefa and Watch Description \(n\)个数的字符串,\(m + k\)个操作 1 l r k把\(l - r\)赋值为\(k\) 2 l r d询 ...
- 【Vjudge】P1989Subpalindromes(线段树)
题目链接 水题一道,用线段树维护哈希值,脑补一下加减乱搞搞……注意细节就过了 一定注意细节…… #include<cstdio> #include<cstdlib> #incl ...
- 【线段树哈希】「Balkan OI 2016」Haker
1A海星 题目大意 给你一个长度为 $n$ ,由小写字母构成的字符串 $S$ 和 $Q$ 个操作,每个操作是以下 3 种之一: 1 x y k :询问当前字符串从位置 $x$ 到 $y$ 的子串与从位 ...
- hdu3973 AC's String 线段树+字符串hash
题目链接:http://icpc.njust.edu.cn/Problem/Hdu/3973/ 题意是:给出一个模式串,再给出一些串组成一个集合,操作分为两种,一种是替换模式串中的一个字符,还有一种是 ...
- N - Subpalindromes URAL - 1989 哈希+线段树
N - Subpalindromes URAL - 1989 这个是一个哈希+线段树,这个题目也不算特别难,但是呢,还比较有意思. 这个题目给你两个操作,一个是回答l~r 区间是不是回文,一个是对一个 ...
随机推荐
- 【mybatis-SqlSession的方法总结】
SqlSession 实例在 MyBatis 中是非常强大的一个类.SqlSession 实例中有所有执行语句的方法,提交或回滚事务,还有获取映射器实例. 在 SqlSession 类中有超过 20 ...
- 缓存处理类(MemoryCache结合文件缓存)
想提升站点的性能,于是增加了缓存,但是站点不会太大,于是不会到分布式memcached的缓存和redis这个nosql库,于是自己封装了.NET内置的缓存组件 原先使用System.Web.Cachi ...
- Codeforces - 102222C - Caesar Cipher
https://codeforc.es/gym/102222/my 好像在哪里见过这个东西?字符的左右移还是小心,注意在mod26范围内. #include<bits/stdc++.h> ...
- BZOJ 1012【线段树】
题意: Q L 询问数列最后 L 个数中最大的数. A n 将 n + t ( t_init = 0 ), 然后插到最后去. 思路: 感觉动态地插入,很有问题. 数组地长度会时常变化,但是可以先预处理 ...
- java解析xml实例——获取天气信息
获取xml并解析其中的数据: package getweather.xml; import java.io.IOException; import java.util.HashMap; import ...
- HDP3.1 中 YRAN 和 MR2 的内存大小配置的计算方式
Container 是 YARN 中基本的处理单元,它是对内存.CPU等计算的封装.总的来说,每个core每块硬盘 分配2个 container,能获得较好的集群利用率. 1. 确定可用内存大小. 对 ...
- Spark 性能调优零散知识
1. 如果 Spark 中 CPU 的使用率不够高,可以考虑为当前的程序分配更多的 Executor, 或者增加更多的 Worker 实例来充分的使用多核的潜能 2. 适当设置 Partition 分 ...
- 2017-10-26 NOIP模拟赛
三分咲 #include<iostream> #include<cstdio> #include<ctime> using namespace std; int n ...
- 根据T-Code查看用户出口的代码
在此非常非常感谢源作者,这段代码真的非常非常有用好用! REPORT YLBTEST. TABLES : tstc, "SAP Transaction Codes(SAP 事务代 ...
- day14内置函数作业详解
day14题目 day14作业及默写 1,整理今天所学内容,整理知识点,整理博客. 2,画好流程图. 3,都完成的做一下作业(下面题都是用内置函数或者和匿名函数结合做出): 4,用map来处理字符串列 ...