题目传送门:洛谷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. log4net日志文件的应用

    日志作为快速定位程序问题的主要手段,日志几乎是所有程序都必须拥有的一部分,下面我们就看下怎么使用log4net.dll文件: 1.下载log4net.dll文件 2.创建自己的项目 3.在自己项目下的 ...

  2. NOIP赛前集训营-提高组(第一场)#B 数数字

    题目描述 小N对于数字的大小一直都有两种看法.第一种看法是,使用字典序的大小(也就是我们常用的判断数字大小的方法,假如比较的数字长度不同,则在较短一个前面补齐前导0,再比较字典序),比如43<3 ...

  3. python2 python3共存解决方案

    作者:匿名用户链接:https://www.zhihu.com/question/21653286/answer/95532074来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注 ...

  4. 【转】Microsoft Visio2010 如何画UML 图

    转载:http://sdoq19.blog.163.com/blog/static/1910392122012419103442292/ 1.在Microsoft Office2010中打开Micro ...

  5. BZOJ 2458 最小三角形 | 平面分治

    BZOJ 2458 最小三角形 题面 一个平面上有很多点,求他们中的点组成的周长最小的三角形的周长. 题解 跟平面最近点对差不多,也是先把区间内的点按x坐标从中间分开,递归处理,然后再处理横跨中线的三 ...

  6. 关于Powershell对抗安全软件(转)

    Windows PowerShell的强大,并且内置,在渗透过程中,也让渗透变得更加有趣.而安全软件的对抗查杀也逐渐开始针对powershell的一切行为.在https://technet.micro ...

  7. Python 使用CPickle和pickle模块进行序列化和反序列化

    #Cpickle使用C语言进行编写的相比pickle来说效率高很多 #-*-coding:utf-8-*-'''序列化操作'''try:    import cPickle as pickleexce ...

  8. Android Studio aidl文件路径自定义问题

    1.aidl旧文件夹中添加的内容无法编译 sourceSets中主要是把把src/main/aidl文件也作为java.srcDirs, resources.srcDirs,这样当编译程序时,AIDL ...

  9. 【agc019F】Yes or No

    Portal -->agc019F Description 给你\(n+m\)个询问,其中\(n\)个的答案是\(Yes\),\(m\)个的答案是\(No\),现在依次回答这些询问,每回答一个询 ...

  10. 统计学习方法:CART算法

    作者:桂. 时间:2017-05-13  14:19:14 链接:http://www.cnblogs.com/xingshansi/p/6847334.html . 前言 内容主要是CART算法的学 ...