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 ...
随机推荐
- C#程序A调用程序B的问题
C#程序A调用程序B,如果程序B中存在 string path1 = System.Environment.CurrentDirectory; 程序A中开启B进程的代码为: System.Diagno ...
- checkbox:全选、全不选、单选(慕课网题目)
任务 1.在第27行处补充完整,实现当点击"全选"按钮时,将选中所有的复选项. 提示:document.getElementsByTagName("input" ...
- html语法第 -2
1 <html> 2 <head> 3 <title>这是第一节课网页标题</title> 4 <meta charset="UTF-8 ...
- Azure PowerShell 在ARM环境下使用指定 vhd(本地化后的磁盘) 来创建虚拟机
#此脚本用于 Azure 存储账户中已有 vhd 镜像文件创建虚拟机,一般用于做好镜像测试 #----------------------------------------------------- ...
- JQuery日期选择器插件date-input
JQuery日期选择器插件之date-input 官方网站:http://jonathanleighton.com/projects/date-input/ 下载地址: http://github.c ...
- NIO入门之轻松读取大文件
NIO入门之轻松读取大文件 今天同事碰到了一个问题,从游戏服务器下载下来的输出log有一个多G大.用记事本打不开,EditPlus也打不开,都提示文件太大.用word也打不开,提示文件大于512M.打 ...
- 循环实现数组filter方法
// 循环实现数组 filter 方法 const selfFilter = function (fn, context){ // 如果调用的地方使用箭头函数,这里的this岂不是不对了,那该怎么解决 ...
- protobuf的Compiler卸载
一.首先,只用remove命令是不起作用的. 二.找寻到进行make的文件夹目录,然后执行make uninstall命令. 三.通过which protoc 命令,找到protoc所在位置,rm p ...
- flex布局以及相关属性
容器的属性: 父元素设置display:flex:子元素即可使用flex布局. flex-direction 决定项目排列方向: .box { flex-direction: row | row-re ...
- sh脚本写法
1.shell注释符号: 1. 单行注释: “#” 2. 多行注释: : << ! 语句1 语句2 语句3 语句4 ! http://blog.csdn.net/lansesl2008/a ...