UVA - 11996 Jewel Magic (Treap+二分哈希)
2024-09-05 13:40:08
维护一个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 ;
}
最新文章
- Oracle 学习方法
- C++ Programming language读书笔记
- (转)原始图像数据和PDF中的图像数据
- Magicodes.WeiChat——WeChatOAuthTest(网页授权获取用户基本信息)
- 【IOS笔记】Using View Controllers in Your App
- YTU 2973: C语言习题5.25--文件操作2
- WebDriver - 添加失败截图
- ubuntu 彻底删除软件包
- zoj 3640 Help Me Escape 概率DP
- 使用Fiddler解析WCF RIA Service传输的数据
- 安装javajava整合Flex
- c# 内存的具体表现- 通用类型系统 深拷贝 浅拷贝 函数传参
- 注意Vietnamese_CI_AS排序规则下的特殊字符大小敏感问题
- 记录使用nodejs时,未正确使用import导致的错误
- web service &;&; WCF 学习小结
- 飞鱼48小时游戏创作嘉年华_厦门Pitch Time总结与收获
- [daily][tcpdump] tcpdump查找reset包
- DataSet &; DataTable &;DataRow 深入浅出
- springmvc 笔记一
- python MQTT 出现TypeError: payload must be a string, bytearray, int, float or None.
热门文章
- 微信小程序遍历wx:for,wx:for-item,wx:key
- Django 邮箱找回密码!!!!!!!!!!!!!!!!
- python高级 之(一) --- 函数类型
- Linux中命令别名alias与命令替换
- 多标签分类(multi-label classification)综述
- java 兔子生仔问题
- Python学习【day04】- Python基础(集合、函数)
- Python验证码登录(Tesseract安装配置)
- Java排序--排序算法(内排序)
- oa_mvc_easyui_详细页(5)