后缀平衡树的裸题

后缀平衡树简单的思想如下 具体的可以去看\(clj\)的论文

假设我们已经有了串\(S\)的后缀平衡树

插入一个字母\(c\)

我们用\(Si\)代表原串\(S\)从第\(i\)个字符开始的后缀

则后缀\(cS\)与任意一个后缀\(Si\)的大小关系可以用

\(c\)与\(Si\)的第一个字母的大小关系

以及 后缀\(S1\)与后缀\(Si+1\)的大小关系来表示

前面是两个字符的比较\(O(1)\)

后面两个原串后缀的大小关系由后缀平衡树所代表其的节点标号快速得出两个后缀大小 \(O(1)\)

于是我们只要维护一个平衡树来\(O(1)\)求出任意后缀的\(rank\) 再建一个线段树来区间查询,单点修改就可以了

#include<bits/stdc++.h>
using namespace std;
#define FO(x) {freopen(#x".in","r",stdin);freopen(#x".out","w",stdout);}
#define pa pair<int,int>
#define mod 1000000007
#define ll long long
#define mk make_pair
#define pb push_back
#define fi first
#define se second
#define lb double
#define cl(x) memset(x,0,sizeof x)
#ifdef Devil_Gary
#define bug(x) cout<<(#x)<<" "<<(x)<<endl
#define debug(...) fprintf(stderr, __VA_ARGS__)
#else
#define bug(x)
#define debug(...)
#endif
const int INF = 0x7fffffff;
const int N=1e6+5;
const lb alpha=0.85;
/*
char *TT,*mo,but[(1<<15)+2];
#define getchar() ((TT==mo&&(mo=(TT=but)+fread(but,1,1<<15,stdin),TT==mo))?-1:*TT++)//*/
inline int read(){
int x=0,rev=0,ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')rev=1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return rev?-x:x;
}
char s[N],ss[5];
int n,m,len,typ,lstans,sit[N],at[N];
lb v[N];
struct SuffixBT{
int ls[N],rs[N],sz[N],sf[N],rt,cnt;
int tmp[N],cc;
int fail,fafail;
lb fl,fr;
bool cmp(int x,int y){
if(!x||!y) return !x;
if(s[x]!=s[y]) return s[x]<s[y];
return v[at[x-1]]<v[at[y-1]];
}
void update(int pos,lb l,lb r){
sz[pos]=sz[ls[pos]]+sz[rs[pos]]+1;
if(max(sz[ls[pos]],sz[rs[pos]])>sz[pos]*alpha) fail=pos,fafail=-1,fl=l,fr=r;
else if(fail==ls[pos]||fail==rs[pos]) fafail=pos;
}
void insert(int&pos,lb l,lb r,int&id){
if(!pos){
v[at[id]=pos=++cnt]=(l+r)/2.0,sz[pos]=1,sf[pos]=id;
return;
}
lb vmid=(l+r)/2.0;
cmp(sf[pos],id)?insert(rs[pos],vmid,r,id):insert(ls[pos],l,vmid,id);
update(pos,l,r);;
}
int rebuild(int nl,int nr,lb l,lb r){
int mid=nl+nr>>1,pos=tmp[mid];
lb vmid=(l+r)/2.0;
v[pos]=vmid,sz[pos]=nr-nl+1;
if(nl<mid) ls[pos]=rebuild(nl,mid-1,l,vmid);
if(nr>mid) rs[pos]=rebuild(mid+1,nr,vmid,r);
return pos;
}
void dfs(int pos){
if(ls[pos]) dfs(ls[pos]);
tmp[++cc]=pos;
if(rs[pos]) dfs(rs[pos]);
ls[pos]=rs[pos]=sz[pos]=0;
}
void insert(int &id){
fail=0,fafail=-1,insert(rt,0,1,id);
if(fail){
cc=0,dfs(fail);
if(fafail!=-1) (fail==ls[fafail])? ls[fafail]=rebuild(1,cc,fl,fr):rs[fafail]=rebuild(1,cc,fl,fr);
else rt=rebuild(1,cc,0,1);
}
}
}sbt;
struct SGT{
int t[N<<2];
bool cmp(int a,int b){
if(sit[a]==sit[b]) return a<b;
return v[at[sit[a]]]<v[at[sit[b]]];
}
void update(int pos){
t[pos]=cmp(t[pos<<1],t[pos<<1|1])?t[pos<<1]:t[pos<<1|1];
}
void build(int pos,int l,int r){
if(l==r){
t[pos]=l;
return;
}
int mid=l+r>>1;
build(pos<<1,l,mid),build(pos<<1|1,mid+1,r),update(pos);
}
void modify(int pos,int l,int r,int x){
if(l==r) return;
int mid=l+r>>1;
if(x<=mid) modify(pos<<1,l,mid,x);
else modify(pos<<1|1,mid+1,r,x);
update(pos);
}
int Query(int pos,int l,int r,int nl,int nr){
if(nl<=l&&r<=nr) return t[pos];
int mid=l+r>>1;
if(nr<=mid) return Query(pos<<1,l,mid,nl,nr);
else if(nl>mid) return Query(pos<<1|1,mid+1,r,nl,nr);
int ql=Query(pos<<1,l,mid,nl,nr),qr=Query(pos<<1|1,mid+1,r,nl,nr);
return cmp(ql,qr)?ql:qr;
}
}sgt;
int main(){
#ifdef Devil_Gary
freopen("in.txt","r",stdin);
#endif
n=read(),m=read(),len=read(),typ=read(),scanf("%s",s+1),reverse(s+1,s+len+1);
for(int i=0;i<=len;i++) s[i]-='a',sbt.insert(i);
for(int i=1;i<=n;i++) sit[i]=read();
sgt.build(1,1,n);
for(int i=1,c,x,l,r;i<=m;i++){
scanf("%s",ss);
if(ss[0]=='I'){
c=read();
if(typ) c^=lstans;
s[++len]=c,sbt.insert(len);
}
else if(ss[0]=='C') x=read(),sit[x]=read(),sgt.modify(1,1,n,x);
else if(ss[0]=='Q') l=read(),r=read(),printf("%d\n",lstans=sgt.Query(1,1,n,l,r));
}
return 0;
}

BZOJ3682 Phorni 后缀平衡树的更多相关文章

  1. 3682: Phorni 后缀平衡树 线段树

    国际惯例的题面: 考虑如果没有强制在线我们能怎么水掉这个题,先构造出字符串,各种方法求一下后缀数组,然后线段树维护区间rank最小的位置即可.然而他要求强制在线,支持插入后缀,并比较后缀大小(求ran ...

  2. 字符串数据结构模板/题单(后缀数组,后缀自动机,LCP,后缀平衡树,回文自动机)

    模板 后缀数组 #include<bits/stdc++.h> #define R register int using namespace std; const int N=1e6+9; ...

  3. BZOJ3682 : Phorni

    后缀平衡树+线段树. $O(1)$比较大小的标号法真是强大. #include<cstdio> #include<cmath> #define N 300010 #define ...

  4. 【XSY2773】基因 后缀平衡树 树套树

    题目描述 有一棵树,每条边上面都有一个字母.每个点还有一个特征值\(a_i\). 定义一个节点\(i\)对应的字符串为从这个点到根的路径上所有边按顺序拼接而成的字符串\(s_i\). 有\(m\)次操 ...

  5. 【COGS2622】后缀平衡树

    这是个后缀平衡树的裸题.... 然后傻逼的我调了一下午. #include<bits/stdc++.h> typedef long long ll; using namespace std ...

  6. 【bzoj3682】Phorni

    后缀平衡树裸题. 后缀平衡树呢,实际上是一个很naive的东西.就是用平衡树维护后缀数组. 这样的话就可以支持在最前端插入一个字符(相当于插入新的后缀) 每次比较节点的tag是O(1)的,所以可以快速 ...

  7. 【BZOJ 3682】Phorni

    题目链接 题目描述 Phorni 是一个音之妖精,喜欢在你的打字机上跳舞. 一天,阳光映射到刚刚淋浴过小雨的城市上时,Phorni 用魔法分裂出了许多个幻影,从 1 到 n 编号. 她的每一个幻影都站 ...

  8. [BZOJ 3682]Phorni

    后缀平衡树的模板题? I'm so weak…… 现在觉得替罪羊树比 treap 好写,是不是没救了喵- #include <cstdio> #include <cmath> ...

  9. UOJ#35 后缀排序

    这是一道模板题. 读入一个长度为 n 的由小写英文字母组成的字符串,请把这个字符串的所有非空后缀按字典序从小到大排序,然后按顺序输出后缀的第一个字符在原串中的位置.位置编号为 1 到 n. 除此之外为 ...

随机推荐

  1. 阿里云服务器搭建FTP

    操作系统:Windows Server 2008 R2企业版. 首先,创建一个用户组:ftpUsers,创建一个用户:ftpAdmin.并将ftpAdmin隶属于ftpUsers组 其次,需要安装ft ...

  2. 利用mysqltuner工具对mysql数据库进行优化

    mysqltuner工具使用,本工具建议定期运行,发现目前MYSQL数据库存在的问题及修改相关的参数 工具的下载及部署 解决环境依赖,因为工具是perl脚本开发的,需要perl脚本环境 # yun i ...

  3. centos6.5下系统编译定制iptables防火墙扩展layer7应用层访问控制功能及应用限制QQ2016上网

    iptables防火墙扩展之layer7应用层访问控制 概述: iptables防火墙是工作在网络层,针对TCP/IP数据包实施过滤和限制,属于典型的包过滤防火墙.以基于网络层的数据包过滤机制为主,同 ...

  4. centos6.5环境使用RPM包离线安装MariaDB 10.0.20

    1. 进入MariaDB官网下载MariaDB需要的RPM包 2. 使用下载软件下载所需要的RPM包, 总共4个, 并上传到CentOS主机指定目录. MariaDB-10.0.20-centos6- ...

  5. [HTML]点击按钮,页面总是跳回顶端的解决方法(Clicking an button,always resets the view to top of page)

    1 前言 当网页页面较长或者表单较多时,右侧会出现滚动条,然而经常会出现点击底部的<button>按钮或者<a>超链接,会出现点击后,当前页面会回到顶端. 2 方案 例如样例代 ...

  6. matplotlib画堆叠条形图

    import matplotlib.pyplot as plt%matplotlib inlineplt.style.use('ggplot') plt.style.use("ggplot& ...

  7. ThinkPHP 3.1.3及之前的版本使用不当可造成SQLi

    Lib/Core/Model.class.php中解析SQL语句的函数parseSql没有对SQL语句进行过滤,使用不当可导致SQL注入.(哈哈,其实用再安全的框架使用不当都可能造成SQLi) 函数: ...

  8. Makefile 隐含规则,模式规则,常见变量

     隐含规则复杂的Makefile一般会使用隐含规则内的变量来简化编译处理.将隐含规则中使用的变量分成两种:一种是命令相关的,如“CC”:一种是参数相关的,如“CFLAGS”.这些变量都是大写表示. 常 ...

  9. Stanford CS231n - Convolutional Neural Networks for Visual Recognition

    网易云课堂上有汉化的视频:http://study.163.com/course/courseLearn.htm?courseId=1003223001#/learn/video?lessonId=1 ...

  10. python 全栈开发,Day65(索引)

    索引 一.索引的介绍 数据库中专门用于帮助用户快速查找数据的一种数据结构.类似于字典中的目录,查找字典内容时可以根据目录查找到数据的存放位置吗,然后直接获取. 二 .索引的作用 约束和加速查找 三.常 ...