题目大意:

不断修改字符串中的字母,然后询问区间字符串是否处于已给定的字符串集合中

这里将原来的字符串集合保存到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的更多相关文章

  1. 线段树 + 字符串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]是 ...

  2. hdu3973 AC's String 线段树+字符串hash

    题目链接:http://icpc.njust.edu.cn/Problem/Hdu/3973/ 题意是:给出一个模式串,再给出一些串组成一个集合,操作分为两种,一种是替换模式串中的一个字符,还有一种是 ...

  3. hdu 3954 线段树 (标记)

    Level up Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  4. 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 ...

  5. hdu 3974 线段树 将树弄到区间上

    Assign the task Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  6. hdu 3436 线段树 一顿操作

    Queue-jumpers Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) To ...

  7. hdu 3397 线段树双标记

    Sequence operation Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  8. hdu 4578 线段树(标记处理)

    Transformation Time Limit: 15000/8000 MS (Java/Others)    Memory Limit: 65535/65536 K (Java/Others) ...

  9. hdu 4533 线段树(问题转化+)

    威威猫系列故事——晒被子 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Tot ...

随机推荐

  1. CentOS 6.9:MySQL Daemon failed to start.

    [root@Server_1 12:02:58 ~ 25]#service mysqld start MySQL Daemon failed to start.Starting mysqld: [ro ...

  2. 在虚拟机里安装windows或Linux系统时,安装窗口过大按钮有时点不到解决办法(图文详解)

    不多说,直接上干货! 问题详情 解决办法 很简单快捷的解决办法,就是快捷键ALT+F7,可以拖动窗口的位置. 成功!

  3. Unity坐标系统

    Unity使用了几种不同的坐标系统,分别如下: 1.屏幕坐标(Screen Space):屏幕坐标是以像素来定义的,以屏幕左下角为(0, 0)点,右上角为(Screen.width, Screen.h ...

  4. Apache Cordova

    http://cordova.apache.org/ Apache Cordova is a platformfor building native mobile applications using ...

  5. AJPFX总结Collection集合(下)

    List集合特有方法 特有方法.凡是可以操作角标的方法都是该体系特有的方法. 增          add(index,element);在指定位置添加元素          addAll(index ...

  6. web前端怎么样才能入门

    web前端怎么样才能入门,首先我们要从什么是初级web前端工程师说起: 按照我的想法,我把前端工程师分为了入门.初级.中级.高级这四个级别: 入门级别指的是了解什么是前端(前端到底是什么其实很多人还是 ...

  7. Android开发中SharedPreferences的使用

    在Android开发中,在储存少量的数据时,个人感觉SharedPreferences是最好的选择,SharedPreferences是以键值对的方式进行储存,支持boolean,int,float, ...

  8. 如何查看安装的java是32位的,还是64位的

    命令 java -d32 -version 或者 java -d64 -version

  9. 程序员必须知道FTP命令

                                             程序员必须知道FTP命令 文件传输软件的使用格式为:FTP<FTP地址>,若连 接成功,系统将提示用户输入 ...

  10. mysql use index() 优化查询

    mysql use index() 优化查询 FORCE INDEX/IGNORE INDEX 的语法: SELECT *** FROM TABLE [{USE|IGNORE|FORCE} INDEX ...