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 ...
随机推荐
- HDU 1221 Rectangle and Circle 考虑很多情况,good题
http://acm.hdu.edu.cn/showproblem.php?pid=1221 114 92 31 95 13 96 3 这题只需要判断圆和矩形是否相交,然后在里面是不算相交的. 那么就 ...
- 【转】Android进程机制
以下资料摘录整理自老罗的Android之旅博客,是对老罗的博客关于Android底层原理的一个抽象的知识概括总结(如有错误欢迎指出)(侵删):http://blog.csdn.net/luosheng ...
- 第3章 接口与API设计 52条笔记
第3章 接口与API设计 52条笔记 第15条: 用前缀避免命名空间冲突 Objective-C 没有其他语言那种内置的命名空间机制 .鉴于此,我们在起名时要设法避免潜在的命名冲突,否则很容易就重名了 ...
- 为sublime Text3 安装插件JS Format
1. 安装package control 菜单 View - Show Console 或者 ctrl + ~ 快捷键,调出 console.将以下 Python 代码粘贴进去并 enter 执行,不 ...
- php用面向对象从mysql取数据
<?php //建立数据库的链接@$_mysqli = new mysqli('localhost','root','123456','dbname');if(mysqli_connect_er ...
- javaee 第四周作业
分析hello.java.下载链接:https://github.com/javaee/tutorial-examples/tree/master/web/jsf/hello1 /** * Copyr ...
- jquery命名冲突
nodeName是jquery的关键字
- execve - 执行程序
总览 (SYNOPSIS) #include <unistd.h> int execve (const char *filename, char *const argv [], char ...
- python3.7 socket通信
def OpenClient(self,e): global line line = socket.socket(socket.AF_INET,socket.SOCK_STREAM) line.bin ...
- nodeJS和npm的环境配置
1.windows下的NodeJS安装是比较方便的(v0.6.0版本之后,支持windows native),只需要登陆官网(http://nodejs.org/),便可以看到首页的“INSTALL” ...