题目传送门:洛谷P4036

题意简述:

有一个字符串,支持插入字符,修改字符。

每次需要查询两个后缀的LCP长度。

最终字符串长度\(\le 100,\!000\),修改和询问的总个数\(\le 150,\!000\),查询操作\(\le 10,\!000\)。

题解:

由后缀和LCP可以想到后缀数组或后缀自动机,但是它们都无法插入或修改。

考虑到LCP可以通过二分+哈希的方式来计算,考虑维护区间的哈希值。

这里使用平衡树无旋Treap来维护区间的哈希值。

一次修改\(O(\log n)\),一次询问\(O(\log^2 n)\)。

bzoj时限略卡,用了自然溢出才过。

 #include<bits/stdc++.h>
using namespace std;
#define Bse 19260817u
unsigned Pow[]; char Str[];
int N,Q;
int ls[],rs[],siz[],pri[],val[],cnt,Root;
unsigned ha[]; unsigned ran(){static unsigned x=;return x^=x<<,x^=x>>,x^=x<<;} void combine(int id){
siz[id]=siz[ls[id]]++siz[rs[id]];
ha[id]=Pow[siz[rs[id]]+]*ha[ls[id]]+Pow[siz[rs[id]]]*val[id]+ha[rs[id]];
} int Merge(int rt1,int rt2){
if(!rt1) return rt2;
if(!rt2) return rt1;
if(pri[rt1]>=pri[rt2]){
rs[rt1]=Merge(rs[rt1],rt2);
combine(rt1);
return rt1;
}
else{
ls[rt2]=Merge(rt1,ls[rt2]);
combine(rt2);
return rt2;
}
} void Split(int rt,int k,int&rt1,int&rt2){
if(!rt) {rt1=rt2=; return;}
if(k<=siz[ls[rt]]){
Split(ls[rt],k,rt1,rt2);
ls[rt]=rt2;
combine(rt);
rt2=rt;
}
else{
Split(rs[rt],k-siz[ls[rt]]-,rt1,rt2);
rs[rt]=rt1;
combine(rt);
rt1=rt;
}
} void Insert(int pos,int v){
val[++cnt]=v, ha[cnt]=v, pri[cnt]=ran(), siz[cnt]=;
int rt1,rt2;
Split(Root,pos,rt1,rt2);
Root=Merge(Merge(rt1,cnt),rt2);
} void Change(int pos,int v){
int rt1,rt2,rt3,rt4;
Split(Root,pos-,rt1,rt2);
Split(rt2,,rt3,rt4);
val[rt3]=v; combine(rt3);
Root=Merge(Merge(rt1,rt3),rt4);
} unsigned chk(int pos,int len){
int rt1,rt2,rt3,rt4;
Split(Root,pos-,rt1,rt2);
Split(rt2,len,rt3,rt4);
unsigned D=ha[rt3];
Root=Merge(Merge(rt1,rt3),rt4);
return D;
} int main(){
Pow[]=; for(int i=;i<=;++i) Pow[i]=Pow[i-]*Bse;
scanf("%s",Str+);
N=strlen(Str+);
for(int i=;i<=N;++i)
Insert(i-,Str[i]);
scanf("%d",&Q);
for(int i=;i<=Q;++i){
int x,y; char opt[];
scanf("%s",opt);
if(*opt=='Q'){
scanf("%d%d",&x,&y);
int l=, r=N-max(x,y)+, mid, ans=;
while(l<=r){
mid=l+r>>;
if(chk(x,mid)==chk(y,mid)) ans=mid, l=mid+;
else r=mid-;
}
printf("%d\n",ans);
}
else if(*opt=='R'){
scanf("%d%s",&x,opt);
Change(x,*opt);
}
else if(*opt=='I'){
scanf("%d%s",&x,opt);
Insert(x,*opt);
++N;
}
}
return ;
} // luogu P4036 - Fhq-Treap + hash. 18:20 ~ 19:03

bzoj 1014: 洛谷 P4036: [JSOI2008]火星人的更多相关文章

  1. 洛谷 P4036 [JSOI2008]火星人(splay+字符串hash)

    题面 洛谷 题解 首先,我们知道求最长公共前缀可以用二分答案+hash来求 因为有修改操作, 考虑将整个字符串的hash值放入splay中 接着就是splay的基本操作了 Code #include& ...

  2. 洛谷 P1198 [JSOI2008]最大数

    洛谷 P1198 [JSOI2008]最大数 题目描述 现在请求你维护一个数列,要求提供以下两种操作: 1. 查询操作. 语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值. ...

  3. [BZOJ 3039&洛谷P4147]玉蟾宫 题解(单调栈)

    [BZOJ 3039&洛谷P4147]玉蟾宫 Description 有一天,小猫rainbow和freda来到了湘西张家界的天门山玉蟾宫,玉蟾宫宫主蓝兔盛情地款待了它们,并赐予它们一片土地. ...

  4. 洛谷P1198 [JSOI2008]最大数(单点修改,区间查询)

    洛谷P1198 [JSOI2008]最大数 简单的线段树单点问题. 问题:读入A和Q时,按照读入一个字符会MLE,换成读入字符串就可以了. #include<bits/stdc++.h> ...

  5. P4036 [JSOI2008]火星人(splay+hash+二分)

    P4036 [JSOI2008]火星人 Splay维护hash,查询二分 $a[x].vl=a[lc].vl*ha[a[rc].sz+1]+a[x].w*ha[a[rc].sz]+a[rc].vl$ ...

  6. 「线段树」「单点修改」洛谷P1198 [JSOI2008]最大数

    「线段树」「单点修改」洛谷P1198 [JSOI2008]最大数 题面描述 现在请求你维护一个数列,要求提供以下两种操作: 1. 查询操作. 语法:Q L 功能:查询当前数列中末尾L个数中的最大的数, ...

  7. 洛谷P1198 [JSOI2008]最大数(BZOJ.1012 )

    To 洛谷.1198 最大数 题目描述 现在请求你维护一个数列,要求提供以下两种操作: 1. 查询操作. 语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值. 限制:L不超过当 ...

  8. 洛谷P1198 [JSOI2008]最大数

    P1198 [JSOI2008]最大数 267通过 1.2K提交 题目提供者该用户不存在 标签线段树各省省选 难度提高+/省选- 提交该题 讨论 题解 记录 最新讨论 WA80的戳这QwQ BZOJ都 ...

  9. BZOJ1015或洛谷1197 [JSOI2008]星球大战

    BZOJ原题链接 洛谷原题链接 发现正着想毫无思路,所以我们可以考虑倒着思考,把摧毁变成建造. 这样很容易想到用并查集来维护连通块,问题也变的很简单了. 建原图,先遍历一遍所有边,若某条边的两端点未被 ...

随机推荐

  1. js 添加事件兼容性

    var tools = { //添加事件 addHandle: function (e, type, handle) { if (e.addEventListener) { e.addEventLis ...

  2. BZOJ3240 NOI2013矩阵游戏(数论)

    必修五题. // luogu-judger-enable-o2 #include<iostream> #include<cstdio> #include<cmath> ...

  3. python中使用%与.format格式化文本

    初学python,看来零零碎碎的格式化文本的方法,总结一下python中格式化文本的方法.使用不当的地欢迎指出谢谢. 1.首先看使用%格式化文本 常见的占位符: 常见的占位符有: %d 整数 %f 浮 ...

  4. [BZOJ2733][HNOI2010]永无乡 解题报告 启发式合并,线段树合并

    好久没更新博客了,前段时间一直都在考试,都没时间些,现在终于有点闲了(cai guai)... 写了一道题,[HNOI2012]永无乡,其实是一道板子题,我发现我写了好多板子题...还是太菜了... ...

  5. 中行P1签名及验签

    分享中国银行快捷.NET P1签名和验签方法代码中ReturnValue为自定义类型请无视 #region 验证签名 /// <summary> /// 验证签名 /// </sum ...

  6. 数据库之Oracle的介绍与使用20180620

    /*******************************************************************************************/ 一.orac ...

  7. 使用kafka消息队列解决分布式事务(可靠消息最终一致性方案-本地消息服务)

    微服务框架Spring Cloud介绍 Part1: 使用事件和消息队列实现分布式事务 本文转自:http://skaka.me/blog/2016/04/21/springcloud1/ 不同于单一 ...

  8. java8 新特性 Stream

    1. Stream初体验 我们先来看看Java里面是怎么定义Stream的: A sequence of elements supporting sequential and parallel agg ...

  9. hihoCoder #1143 : 骨牌覆盖问题·一

    #1143 : 骨牌覆盖问题·一 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 骨牌,一种古老的玩具.今天我们要研究的是骨牌的覆盖问题:我们有一个2xN的长条形棋盘,然 ...

  10. UNDERSTANDING THE GAUSSIAN DISTRIBUTION

    UNDERSTANDING THE GAUSSIAN DISTRIBUTION Randomness is so present in our reality that we are used to ...