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 ...
随机推荐
- asp.net MVC 错误信息“没有为该对象定义无参数的构造函数”请求各位大神帮忙!
在做一个登录的功能,没有用MVC自己生成的identity代码,仿照别人的代码写出了以后出现错误. 错误信息如下: 代码如下: 求各位asp.net大神支招,网上找了资料最终也没解决这个问题.
- AJPFX关于Swing组件的总结
默认布局管理器是流式布局(FlowLayout) 按钮的建立: jb1=new JButton("香蕉") 面板的建立:jp1=new JPanel(); 设置JFrame的标题: ...
- 微信小程序 逻辑层
1. 注册程序小程序APP在小程序的根目录下有一个app.js文件.有App(Object),App() 函数用来注册一个小程序.接受一个 Object 参数,其内便是小程序的生命周期.App() 必 ...
- iOS逆向实战与工具使用(微信添加好友自动确认)
iOS逆向实战与工具使用(微信添加好友自动确认) 原文链接 源码地址 WeChatPlugin-iOS Mac OS 版微信小助手(远程控制.消息防撤回.自动回复.微信多开) 一.前言 本篇主要实现在 ...
- 分类IP地址(A、B、C类)的指派范围、一般不使用的特殊IP地址
分类IP地址(A.B.C类)的指派范围.一般不使用的特殊IP地址 A类地址:0开头,8位网络号 B类地址:10开头,16位网络号 C类地址:110开头,24位网络号 D类地址:1110开头,多播地址 ...
- (转)编码剖析Spring装配基本属性的原理
http://blog.csdn.net/yerenyuan_pku/article/details/52856465 上回我们已经讲到了Spring依赖注入的第一种方式,现在我们来详解第二种方式,须 ...
- 细说PHP-5.3.4变量的引用赋值
变量总是传值赋值.也就是说,当讲一个表达式的值赋予一个变量时,整个原始表达式的值被赋值到目标变量.这意味着,当一个变量的值赋予另个一变量时,改变其中一个变量的值,将不会影响到另一个变量.PHP中提供了 ...
- WPF知识点全攻略01- WPF相对WinFrom的优缺点
对比WPF和WinFrom前,先来了解下GUI现阶段在用的其他一些开发技术: MFC:微软基础类库,以C++的形式封装了Windows API,加上一些实用工具类. QT:奇趣科技开发的跨平台C++图 ...
- 最短路 || POJ 1847 Tram
POJ 1847 最短路 每个点都有初始指向,问从起点到终点最少要改变多少次点的指向 *初始指向的那条边长度为0,其他的长度为1,表示要改变一次指向,然后最短路 =========高亮!!!===== ...
- myBatis参数处理 myBatis佟刚课程笔记
单个参数:myBatis不会做特殊处理 #{参数名}: 取出参数值 多个参数: myBatis会做特殊处理 多个参数会被封装成一个MAP key:param1 param2.... param10,或 ...