维护一个01序列,一共四种操作:

1.插入一个数

2.删除一个数

3.反转一个区间

4.查询两个后缀的LCP

用Splay或者Treap都可以做,维护哈希值,二分求LCP即可。

注意反转序列的时候序列的哈希值也会改变,因此需要维护正反两个哈希值,在交换左右儿子的时候顺便交换两个哈希值即可。

还有就是打标记的同时也要进行反转,不要等pushdown的时候再反转

 #include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ll;
const int N=4e5+,M=1e9+;
int n,m,ch[N][],siz[N],re[N],val[N],tot,rt;
ll h1[N],h2[N],pm[N];
char s[N];
#define l(u) ch[u][0]
#define r(u) ch[u][1]
#define mid ((l+r)>>1)
int newnode(int x) {int u=++tot; l(u)=r(u)=re[u]=,siz[u]=,val[u]=h1[u]=h2[u]=x; return u;}
void pu(int u) {
siz[u]=siz[l(u)]+siz[r(u)]+;
h1[u]=h1[l(u)]*pm[siz[r(u)]+]+val[u]*pm[siz[r(u)]]+h1[r(u)];
h2[u]=h2[r(u)]*pm[siz[l(u)]+]+val[u]*pm[siz[l(u)]]+h2[l(u)];
}
void rv(int u) {swap(l(u),r(u)),swap(h1[u],h2[u]),re[u]^=;}
void pd(int u) {if(re[u])re[u]=,rv(l(u)),rv(r(u));}
void sp(int w,int k,int& u,int& v) {
if(!w) {u=v=; return;}
pd(w);
if(k>=siz[l(w)]+)u=w,sp(r(w),k-(siz[l(w)]+),r(u),v),pu(u);
else v=w,sp(l(w),k,u,l(v)),pu(v);
}
void mg(int& w,int u,int v) {
if(!u||!v) {w=u|v; return;}
if(rand()%(siz[u]+siz[v])<siz[u])pd(u),w=u,mg(r(w),r(u),v);
else pd(v),w=v,mg(l(w),u,l(v));
pu(w);
}
void ins(int& u,int p,int x) {
int L,R;
sp(u,p,L,R),mg(L,L,newnode(x)),mg(u,L,R);
}
void del(int& u,int p) {
int L,M,R;
sp(u,p,L,R),sp(L,p-,L,M),mg(u,L,R);
}
void rev(int& u,int l,int r) {
int L,M,R;
sp(u,r,L,R),sp(L,l-,L,M);
rv(M);
mg(L,L,M),mg(u,L,R);
}
ll H(int& u,int l,int r) {
int L,M,R;
sp(u,r,L,R),sp(L,l-,L,M);
ll ret=h1[M];
mg(L,L,M),mg(u,L,R);
return ret;
}
int lcp(int& u,int L,int R) {
int l=,r=n-R+,ret;
while(l<=r) {
if(H(u,L,L+mid-)==H(u,R,R+mid-))ret=mid,l=mid+;
else r=mid-;
}
return ret;
}
void build(int& u,int l=,int r=n) {
if(l>r)return;
u=newnode(s[mid-]-''+);
build(l(u),l,mid-),build(r(u),mid+,r),pu(u);
}
int main() {
srand(time());
pm[]=;
for(int i=; i<N; ++i)pm[i]=pm[i-]*M;
while(scanf("%d%d",&n,&m)==) {
scanf("%s",s);
tot=,build(rt);
while(m--) {
int f,a,b;
scanf("%d%d",&f,&a);
if(f!=)scanf("%d",&b);
if(f==)ins(rt,a,b+),n++;
else if(f==)del(rt,a),n--;
else if(f==)rev(rt,a,b);
else if(f==)printf("%d\n",lcp(rt,a,b));
}
}
return ;
}

最新文章

  1. Oracle 学习方法
  2. C++ Programming language读书笔记
  3. (转)原始图像数据和PDF中的图像数据
  4. Magicodes.WeiChat——WeChatOAuthTest(网页授权获取用户基本信息)
  5. 【IOS笔记】Using View Controllers in Your App
  6. YTU 2973: C语言习题5.25--文件操作2
  7. WebDriver - 添加失败截图
  8. ubuntu 彻底删除软件包
  9. zoj 3640 Help Me Escape 概率DP
  10. 使用Fiddler解析WCF RIA Service传输的数据
  11. 安装javajava整合Flex
  12. c# 内存的具体表现- 通用类型系统 深拷贝 浅拷贝 函数传参
  13. 注意Vietnamese_CI_AS排序规则下的特殊字符大小敏感问题
  14. 记录使用nodejs时,未正确使用import导致的错误
  15. web service &amp;&amp; WCF 学习小结
  16. 飞鱼48小时游戏创作嘉年华_厦门Pitch Time总结与收获
  17. [daily][tcpdump] tcpdump查找reset包
  18. DataSet &amp; DataTable &amp;DataRow 深入浅出
  19. springmvc 笔记一
  20. python MQTT 出现TypeError: payload must be a string, bytearray, int, float or None.

热门文章

  1. 微信小程序遍历wx:for,wx:for-item,wx:key
  2. Django 邮箱找回密码!!!!!!!!!!!!!!!!
  3. python高级 之(一) --- 函数类型
  4. Linux中命令别名alias与命令替换
  5. 多标签分类(multi-label classification)综述
  6. java 兔子生仔问题
  7. Python学习【day04】- Python基础(集合、函数)
  8. Python验证码登录(Tesseract安装配置)
  9. Java排序--排序算法(内排序)
  10. oa_mvc_easyui_详细页(5)