HDU 3973 线段树+字符串hash
题目大意:
不断修改字符串中的字母,然后询问区间字符串是否处于已给定的字符串集合中
这里将原来的字符串集合保存到hash表中,当然用map,set都没有问题
修改查询都用线段树实现,自己的query函数写的有问题,按照网上的改了就没问题
写一下自己的理解,因为左右子树合并的时候,需要计算右子树生成的字符串的长度后,加上base的长度次方
而我们计算右子树中含有的字母数量,靠t-m , 而这个t 必然要处于 l , r 中,向下递归的时候注意修改s,t的区间,不然计算的长度会偏长
#include <cstdio>
#include <cstring>
#include <map>
#include <set>
#include <iostream>
#define maxn 100010
#define ls o<<1
#define rs o<<1|1
#define define_m int m=(l+r)>>1
#define base 33
#define MOD 1000007
using namespace std;
typedef unsigned long long ULL; ULL val[maxn<<] , fac[maxn];
int size[maxn<<] , head[MOD+] , k;
char str[]; struct HashNode{
ULL val;
int next;
}_hash[MOD]; void insert(ULL key)
{
int pos = key%MOD;
_hash[k].val = key , _hash[k].next = head[pos];
head[pos] = k++;
} bool search(ULL key)
{
int pos = key%MOD;
for(int i=head[pos] ; ~i ; i=_hash[i].next)
if(key == _hash[i].val) return true;
return false;
} void init()
{
fac[]=;
for(int i=;i<maxn;i++)
fac[i]=fac[i-]*base;
memset(head , - , sizeof(head));
k=;
} void push_up(int o)
{
val[o] = val[ls]*fac[size[rs]]+val[rs];
} void build(int o , int l , int r)
{
size[o] = r-l+;
if(l==r){
val[o] = (ULL)str[l];
return ;
}
define_m;
build(ls , l , m);
build(rs , m+ , r);
push_up(o);
} void update(int o , int l , int r , int pos)
{
if(l==r && l==pos){
val[o] = (ULL)str[l];
return ;
}
define_m;
if(m>=pos) update(ls , l , m , pos);
else update(rs , m+ , r , pos);
push_up(o);
} ULL query(int o , int l , int r , int s , int t)
{
if(l>=s&&r<=t){
return val[o];
}
define_m;
if(m>=t) return query(ls , l , m , s , t);
else if(m<s) return query(rs , m+ , r , s , t);
else return query(ls , l , m , s , m)*fac[t-m]+query(rs , m+ , r , m+ , t);//注意后面一个函数中左边界由s改为m+1
} int main()
{
#ifndef ONLINE_JUDGE
freopen("a.in" , "r" , stdin);
#endif // ONLINE_JUDGE
int T,q,n,cas=;
char qu[];
init();
scanf("%d",&T); while(T--)
{
printf("Case #%d:\n",++cas);
scanf("%d",&n);
for(int i=;i<=n;i++){
scanf("%s",str);
ULL cur = ;
for(int j= ; j<strlen(str) ; j++)
cur = cur*base+(ULL)str[j];
insert(cur);
}
scanf("%s",str);
int len=strlen(str);
build(,,len-);
scanf("%d",&q);
int pos,s,t;
for(int i=;i<=q;i++){
scanf("%s",qu);
if(qu[]=='C'){
scanf("%d%s",&pos,qu);
str[pos]=qu[];
update(,,len-,pos);
}
else{
scanf("%d %d",&s,&t);
if(search(query(,,len-,s,t))) printf("Yes\n");
else printf("No\n");
}
}
}
return ;
}
HDU 3973 线段树+字符串hash的更多相关文章
- 线段树 + 字符串Hash - Codeforces 580E Kefa and Watch
Kefa and Watch Problem's Link Mean: 给你一个长度为n的字符串s,有两种操作: 1 L R C : 把s[l,r]全部变为c; 2 L R d : 询问s[l,r]是 ...
- hdu3973 AC's String 线段树+字符串hash
题目链接:http://icpc.njust.edu.cn/Problem/Hdu/3973/ 题意是:给出一个模式串,再给出一些串组成一个集合,操作分为两种,一种是替换模式串中的一个字符,还有一种是 ...
- hdu 3954 线段树 (标记)
Level up Time Limit: 10000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- hdu 5877 线段树(2016 ACM/ICPC Asia Regional Dalian Online)
Weak Pair Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Total ...
- hdu 3974 线段树 将树弄到区间上
Assign the task Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- hdu 3436 线段树 一顿操作
Queue-jumpers Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) To ...
- hdu 3397 线段树双标记
Sequence operation Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...
- hdu 4578 线段树(标记处理)
Transformation Time Limit: 15000/8000 MS (Java/Others) Memory Limit: 65535/65536 K (Java/Others) ...
- hdu 4533 线段树(问题转化+)
威威猫系列故事——晒被子 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) Tot ...
随机推荐
- Linux下用matplotlib画决策树
1.trees = {'no surfacing': { 0: 'no', 1: {'flippers': {0: 'no', 1: 'yes'}}}} 2.从我的文件trees.txt里读的决策树, ...
- CSS div 塌陷问题
嵌套塌陷 上下塌陷 overflow:hidden;
- C#之九大视图
本节向大家介绍一下有关UML视图方面的内容,UML视图共有9种,它们之间有什么区别和联系呢,下面就让我们一起来学习吧,相信通过本节的介绍你一定会有不少收获. UML视图 UML总共提供了9种视图,这些 ...
- Haproxy+Rabbitmq中的问题
问题一.Rabbitmq集群搭建完成 某个集群节宕机后 无法添加失败 解决办法:停掉所有Rabbitmq服务 并删除集群文件C\Users\Administrator\AppData\Roaming\ ...
- [Java 8] (8) Lambda表达式对递归的优化(上) - 使用尾递归 .
递归优化 很多算法都依赖于递归,典型的比如分治法(Divide-and-Conquer).但是普通的递归算法在处理规模较大的问题时,常常会出现StackOverflowError.处理这个问题,我们可 ...
- 接口自动化- 基于 Python
准备工作 这部分其实在谷歌或者百度上搜索下就可以完成的,可是我就是想再啰嗦一遍,说不定有比我更懒的同学呢哈哈~ 第一步 Python的安装配置 打开官网: https://www.python.org ...
- HYSBZ 1588 营业额统计 (Splay树)
题意:给出一个公司每一天的营业额,求每天的最小波动值之和.该天的最小波动值= min { 绝对值| 该天以前某一天的营业额-该天的营业额 | }.第一天的最小波动值就是其自己. 思路:Splay伸展树 ...
- 计数器:counter
组成:2属性,1方法 属性1: counter-reset 命名 属性2: counter-increment 启动/自增 方法 : counter()/counters() 调用方法 1.计数器 命 ...
- js中的函数编程
之前在网上看到了一篇教你如何用js写出装逼的代码. 经过学些以及扩展很有收获在这里记录一下. 原文章找不到了.所以就不在这附上链接了. 大家看下下面两段js代码. 上面两端代码效果是一模一样的,都是在 ...
- AIX 11203 ASM RAC安装
1:查看系统版本 [rac1:root:/hacmp/hacmp5.4/ha5.4/installp/ppc] oslevel -s 6100-06-06-1140 lslpp -al bos.adt ...