动态询问LCP,所以我们不好用后缀数组
考虑使用维护序列问题的splay+hash求LCP
这里mark一下,hash求LCP常用mo=9875321
自然溢出的话交上去莫名其妙WA了
这里树上某节点hash值代表的是这棵子树所代表的序列hash值
求LCP时,只要二分答案然后提取区间判断hash是否相同即可,实践证明错误率很小
这里注意要尽量少取模运算,否则会TLE

 const mo=;
var son:array[-..,..] of longint;
count,fa,hash,a:array[-..] of longint;
d:array[..] of longint;
m,n,root,i,x,y,s:longint;
ch:char; procedure update(x:longint);
var l,r:longint;
begin
l:=son[x,];
r:=son[x,];
count[x]:=count[l]+count[r]+;
hash[x]:=hash[l]+a[x]*d[count[l]]+int64(hash[r])*int64(d[count[l]+]) mod mo; //计算hash
hash[x]:=hash[x] mod mo;
end; function find(k:longint):longint;
var p:longint;
begin
p:=root;
while true do
begin
if count[son[p,]]+=k then exit(p);
if count[son[p,]]+>k then p:=son[p,]
else begin
k:=k-count[son[p,]]-;
p:=son[p,];
end;
end;
end; procedure rotate(x,w:longint);
var y:longint;
begin
y:=fa[x];
if fa[y]<>- then
begin
if son[fa[y],]=y then son[fa[y],]:=x
else son[fa[y],]:=x;
end
else root:=x;
fa[x]:=fa[y];
son[y,-w]:=son[x,w];
if son[x,w]<>- then fa[son[x,w]]:=y;
son[x,w]:=y;
fa[y]:=x;
update(y);
end; procedure splay(x,f:longint);
var y:longint;
begin
while fa[x]<>f do
begin
y:=fa[x];
if fa[y]=f then
begin
if son[y,]=x then rotate(x,)
else rotate(x,);
end
else begin
if son[fa[y],]=y then
begin
if son[y,]=x then rotate(y,) else rotate(x,);
rotate(x,);
end
else begin
if son[y,]=x then rotate(x,) else rotate(y,);
rotate(x,);
end;
end;
end;
update(x); //这是学LCT的时候发现的一个优化,每次rotate只要update父节点即可,这样一下子快了2s多
end; procedure insert(x,y:longint);
begin
x:=find(x+);
splay(x,-);
inc(n);
a[n]:=y;
son[n,]:=son[x,];
fa[son[x,]]:=n;
son[x,]:=n;
fa[n]:=x;
update(n);
update(x);
end; procedure change(x,y:longint);
begin
x:=find(x+);
splay(x,-);
a[x]:=y;
update(x);
end; function build(l,r:longint):longint;
var m:longint;
begin
m:=(l+r) shr ;
build:=m;
if l<=m- then
begin
son[m,]:=build(l,m-);
fa[son[m,]]:=m;
end;
if m+<=r then
begin
son[m,]:=build(m+,r);
fa[son[m,]]:=m;
end;
update(m);
end; function check(x,l,r:longint):longint;
var y:longint;
begin
y:=find(l+r+);
splay(x,-);
splay(y,x);
exit(hash[son[y,]]);
end; function ask(x,y:longint):longint;
var l,r,m,wx,wy:longint;
begin
l:=;
r:=n-y;
if n-x<r then r:=n-x;
ask:=;
wx:=find(x);
wy:=find(y);
while l<=r do
begin
m:=(l+r) shr ;
if check(wx,x,m)=check(wy,y,m) then
begin
l:=m+;
ask:=m;
end
else r:=m-;
end;
end; begin
fillchar(son,sizeof(son),);
fillchar(fa,sizeof(fa),);
read(ch);
while (ch>='a') and (ch<='z') do
begin
inc(n);
a[n]:=ord(ch)-;
read(ch);
end;
readln(m);
d[]:=;
for i:= to do
d[i]:=d[i-]* mod mo;
root:=build(,n+);
inc(n);
for i:= to m do
begin
read(ch);
if ch='Q' then
begin
readln(x,y);
writeln(ask(x,y));
end
else if ch='I' then
begin
read(x);
read(ch);
readln(ch);
y:=ord(ch)-;
insert(x,y);
end
else if ch='R' then
begin
read(x);
read(ch);
readln(ch);
y:=ord(ch)-;
change(x,y);
end;
end;
end.

bzoj1014的更多相关文章

  1. [BZOJ1014][JSOI2008]火星人prefix

    [BZOJ1014][JSOI2008]火星人prefix 试题描述 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam,我们将这个字符串的各个字 ...

  2. BZOJ1014 JSOI2008火星人(splay+哈希)

    splay维护哈希值即可. #include<iostream> #include<cstdio> #include<cmath> #include<cstd ...

  3. 【BZOJ1014】火星人(Splay,哈希)

    [BZOJ1014]火星人(Splay,哈希) 题面 BZOJ 题解 要动态维护这个串,一脸的平衡树. 那么用\(Splay\)维护这个哈希值就好了. 每次计算答案的时候二分+Splay计算区间哈希值 ...

  4. BZOJ1014 JSOI2008 火星人prefix 【非旋转Treap】*

    BZOJ1014 JSOI2008 火星人prefix Description 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam,我们将这个字符 ...

  5. 【bzoj1014】: [JSOI2008]火星人prefix 平衡树-字符串-hash-二分

    [bzoj1014]: [JSOI2008]火星人 用平衡树维护字符串的hash 然后询问的时候二分一下就好了 /* http://www.cnblogs.com/karl07/ */ #includ ...

  6. 无旋Treap - BZOJ1014火星人 & 可持久化版文艺平衡树

    !前置技能&概念! 二叉搜索树 一棵二叉树,对于任意子树,满足左子树中的任意节点对应元素小于根的对应元素,右子树中的任意节点对应元素大于根对应元素.换言之,就是满足中序遍历为依次访问节点对应元 ...

  7. BZOJ1014火星人prefix Splay維護序列 + 字符串哈希

    @[Splay, 哈希] Description 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:\(madamimadam\), 我们将这个字符串的各个字符予以标号 ...

  8. 【BZOJ1014】[JSOI2008]火星人prefix Splay+hash

    [BZOJ1014][JSOI2008]火星人prefix Description 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam,我们将这个 ...

  9. [bzoj1014][JSOI2008]火星人prefix_非旋转Treap_hash_二分

    火星人prefix bzoj-1014 JSOI-2004 题目大意:给定一个字符串,支持三种操作:1.查询:两个后缀之间的$LCP$:2.单点修改:3.插入一个字符. 注释:$1\le n\le 1 ...

  10. 【BZOJ-1014】火星人prefix Splay + 二分 + Hash

    1014: [JSOI2008]火星人prefix Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 5852  Solved: 1871[Submit] ...

随机推荐

  1. CentOS允许/禁止ping的方法

    一.临时生效 1.允许ping >/proc/sys/net/ipv4/icmp_echo_ignore_all 2.禁止ping >/proc/sys/net/ipv4/icmp_ech ...

  2. apache目录及文件讲解

    apache目录下bin,conf,htdocs,logs,modules讲解    bin:        ab  压力测试工具        apachectl  启动命令        apxs ...

  3. user.table.column, table.column 或列说明无效

    Oracle统计采用别名出错(user.table.column, table.column 或列说明无效) >>>>>>>>>>>& ...

  4. 整理收藏一份PHP高级工程师的笔试…

    注:本文转自 http://www.icultivator.com/p/5535.html 注:本文转自 http://www.yiichina.com/tutorial/57 整理了一份PHP高级工 ...

  5. PHP 给前面或者后面添加0补位

    相信大家一定遇到这样的问题,因为PHP是弱类型的,所以进行排序的时候,有时候很胃疼 所以这里就需要将位数进行统一后进行处理 一般都是将末尾添加0进行补位 方法1 :  str_pad — 使用另一个字 ...

  6. git 常见问题收集(持续更新中)

    1.问题:在配置完成github上的ssh后如何使用ssh? 答: 1)http方式 url =https://github.com/username/test_repo.git 2)ssh方式:把u ...

  7. SGU Volume 1

    SGU 解题报告(持续更新中...Ctrl+A可看题目类型): SGU101.Domino(多米诺骨牌)------------★★★type:图 SGU102.Coprimes(互质的数) SGU1 ...

  8. v880 debug

    zte v880手机,ubuntu中配置真机调试, 1.开启手机调试模式2.增加/etc/udev/rules.d/51-android.rules. 内容如下:SUBSYSTEM=="us ...

  9. Linux权限体系总结

    总结 1.  LINUX9位权限及rwx字符的作用.对应的数字及对应的用户和用户组图解. 2.  rwx对文件来说代表什么意思. 3.  rwx对目录来说代表什么意思. 4.  企业生产环境目录设置权 ...

  10. c语言的数组指针与指针数组

    1. 数组指针:指向数组的指针是数组指针 先看下面一段代码: #include <stdio.h> int main(void) { int m[10]; printf("m = ...