思路

splay维护序列的hash值即可

因为有rev操作,还要维护反串的hash值

代码

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
unsigned long long my_pow[600000];
const int base=131;
struct Node{
unsigned long long hashx,hashx_rev;
int son[2],inv,sz,val,fa;
}SPT[600000];
int Nodecnt,root,a[600000],len,n,m;
void get_my_pow(void){
my_pow[0]=1;
for(int i=1;i<=500000;i++)
my_pow[i]=my_pow[i-1]*base;
}
void init(void){
Nodecnt=root=len=0;
memset(SPT,0,sizeof(SPT));
memset(a,0,sizeof(a));
}
void pushup(int o){
SPT[o].sz=SPT[SPT[o].son[0]].sz+SPT[SPT[o].son[1]].sz+1;
SPT[o].hashx=SPT[SPT[o].son[0]].hashx*my_pow[SPT[SPT[o].son[1]].sz+1]+SPT[o].val*my_pow[SPT[SPT[o].son[1]].sz]+SPT[SPT[o].son[1]].hashx;
SPT[o].hashx_rev=SPT[SPT[o].son[1]].hashx_rev*my_pow[SPT[SPT[o].son[0]].sz+1]+SPT[o].val*my_pow[SPT[SPT[o].son[0]].sz]+SPT[SPT[o].son[0]].hashx_rev;
}
void pushdown(int o){
if(o&&SPT[o].inv){
if(SPT[o].son[0]){
swap(SPT[SPT[o].son[0]].son[0],SPT[SPT[o].son[0]].son[1]);
SPT[SPT[o].son[0]].inv^=1;
swap(SPT[SPT[o].son[0]].hashx,SPT[SPT[o].son[0]].hashx_rev);
}
if(SPT[o].son[1]){
swap(SPT[SPT[o].son[1]].son[0],SPT[SPT[o].son[1]].son[1]);
SPT[SPT[o].son[1]].inv^=1;
swap(SPT[SPT[o].son[1]].hashx,SPT[SPT[o].son[1]].hashx_rev);
}
SPT[o].inv^=1;
}
}
int find(int val,int o){
if(!o)
return 0;
pushdown(o);
if(val==SPT[SPT[o].son[0]].sz+1)
return o;
else if(val<=SPT[SPT[o].son[0]].sz)
return find(val,SPT[o].son[0]);
else
return find(val-SPT[SPT[o].son[0]].sz-1,SPT[o].son[1]);
}
int new_node(int val,int fa){
int o=++Nodecnt;
SPT[o].hashx=SPT[o].hashx_rev=SPT[o].val=val;
SPT[o].inv=0;
SPT[o].sz=1;
SPT[o].fa=fa;
SPT[o].son[0]=SPT[o].son[1]=0;
return o;
}
int build(int l,int r,int f){
if(l>r)
return 0;
int mid=(l+r)>>1;
int o=new_node(a[mid],f);
SPT[o].son[0]=build(l,mid-1,o);
SPT[o].son[1]=build(mid+1,r,o);
pushup(o);
return o;
}
int isrl(int o){
return SPT[SPT[o].fa].son[1]==o;
}
void rorate(int o){
int f=SPT[o].fa;
int g=SPT[f].fa;
pushdown(f);
pushdown(o);
int which=isrl(o);
if(g)
SPT[g].son[SPT[g].son[1]==f]=o;
SPT[o].fa=g;
SPT[f].son[which]=SPT[o].son[which^1];
SPT[SPT[o].son[which^1]].fa=f;
SPT[o].son[which^1]=f;
SPT[f].fa=o;
pushup(f);
pushup(o);
}
void splay(int o,int goal){
for(int f;(f=SPT[o].fa)!=goal;rorate(o))
if(SPT[f].fa!=goal)
rorate(isrl(f)==isrl(o)?f:o);
if(!goal)
root=o;
}
void debug(int o){
if(!o)
return;
pushdown(o);
debug(SPT[o].son[0]);
if(SPT[o].val>=0&&SPT[o].val<=1)
printf("%d",SPT[o].val);
else
printf(" %d ",SPT[o].val);
debug(SPT[o].son[1]);
}
void insert(int p,int c){
len++;
int t=new_node(c,0);
int lx=p,rx=p+1;
int lxx=find(lx+1,root),rxx=find(rx+1,root);
splay(lxx,0);
splay(rxx,lxx);
pushdown(root);
pushdown(SPT[root].son[1]);
SPT[SPT[root].son[1]].son[0]=t;
SPT[t].fa=SPT[root].son[1];
pushup(SPT[root].son[1]);
pushup(root);
}
void del(int p){
len--;
int lx=p-1,rx=p+1;
int lxx=find(lx+1,root),rxx=find(rx+1,root);
splay(lxx,0);
splay(rxx,lxx);
pushdown(root);
pushdown(SPT[root].son[1]);
SPT[SPT[root].son[1]].son[0]=0;
pushup(SPT[root].son[1]);
pushup(root);
}
void rev(int l,int r){
int lx=l-1,rx=r+1;
int lxx=find(lx+1,root),rxx=find(rx+1,root);
splay(lxx,0);
splay(rxx,lxx);
pushdown(root);
pushdown(SPT[root].son[1]);
int o=SPT[SPT[root].son[1]].son[0];
SPT[o].inv^=1;
swap(SPT[o].son[0],SPT[o].son[1]);
swap(SPT[o].hashx,SPT[o].hashx_rev);
}
bool check(int p1,int p2,int x){
if(x==0)
return true;
unsigned long long hash1,hash2;
{
int lx=p1-1,rx=p1+x;
int lxx=find(lx+1,root),rxx=find(rx+1,root);
splay(lxx,0);
splay(rxx,lxx);
pushdown(root);
pushdown(SPT[root].son[1]);
hash1=SPT[SPT[SPT[root].son[1]].son[0]].hashx;
}
{
int lx=p2-1,rx=p2+x;
int lxx=find(lx+1,root),rxx=find(rx+1,root);
splay(lxx,0);
splay(rxx,lxx);
pushdown(root);
pushdown(SPT[root].son[1]);
hash2=SPT[SPT[SPT[root].son[1]].son[0]].hashx;
}
return hash1==hash2;
}
int lcp(int p1,int p2){
int l=0,r=min(len-p1+1,len-p2+1),ans=0;
while(l<=r){
int mid=(l+r)>>1;
if(check(p1,p2,mid))
ans=mid,l=mid+1;
else
r=mid-1;
}
return ans;
}
int main(){
get_my_pow();
while(scanf("%d %d",&n,&m)==2){
init();
len=n;
for(int i=2;i<=n+1;i++){
char c=getchar();
while(c!='0'&&c!='1')
c=getchar();
a[i]=c-'0';
}
a[1]=-0x3f3f3f3f;
a[n+2]=0x3f3f3f3f;
root=build(1,n+2,0);
for(int i=1;i<=m;i++){
int opt,p1,p2,c;
scanf("%d",&opt);
if(opt==1){
scanf("%d %d",&p1,&c);
insert(p1,c);
}
else if(opt==2){
scanf("%d",&p1);
del(p1);
}
else if(opt==3){
scanf("%d %d",&p1,&p2);
rev(p1,p2);
}
else{
scanf("%d %d",&p1,&p2);
printf("%d\n",lcp(p1,p2));
}
}
}
return 0;
}

UVA11996 Jewel Magic的更多相关文章

  1. Jewel Magic UVA - 11996 || bzoj1014: [JSOI2008]火星人prefix

    Jewel Magic UVA - 11996 这是一道用splay/非旋treap做的题(这里用的是非旋treap) 1/2/3是splay/非旋treap的常规操作.对于操作4,可以用哈希法求LC ...

  2. UVa 11996 Jewel Magic (splay + Hash + 二分)

    题意:给定一个长度为n的01串,你的任务是依次执行如表所示的m条指令: 1 p c 在第p个字符后插入字符,p = 0表示在整个字符串之前插入2 p 删除第p个字符,后面的字符往前移3 p1 p2反转 ...

  3. UVA - 11996 Jewel Magic (Treap+二分哈希)

    维护一个01序列,一共四种操作: 1.插入一个数 2.删除一个数 3.反转一个区间 4.查询两个后缀的LCP 用Splay或者Treap都可以做,维护哈希值,二分求LCP即可. 注意反转序列的时候序列 ...

  4. UVA 11996 Jewel Magic —— splay、序列的分裂与合并、LCP的哈希算法

    #include <cstdio> #include <cstdlib> #include <iostream> #include <algorithm> ...

  5. Ceph Jewel 10.2.3 环境部署

    Ceph 测试环境部署 本文档内容概要 测试环境ceph集群部署规划 测试环境ceph集群部署过程及块设备使用流程 mon节点扩容及osd节点扩容方法 常见问题及解决方法 由于暂时没有用到对象存储,所 ...

  6. BestCoder Round #25 1002 Harry And Magic Box [dp]

    传送门 Harry And Magic Box Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/ ...

  7. Codeforces CF#628 Education 8 D. Magic Numbers

    D. Magic Numbers time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...

  8. [8.3] Magic Index

    A magic index in an array A[0...n-1] is defined to be an index such that A[i] = i. Given a sorted ar ...

  9. Python魔术方法-Magic Method

    介绍 在Python中,所有以"__"双下划线包起来的方法,都统称为"Magic Method",例如类的初始化方法 __init__ ,Python中所有的魔 ...

随机推荐

  1. Django之JWT理解及简单应用

    Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(S ...

  2. Redis之基本使用

    基本介绍 Redis是一种key-value存储形式的非关系型数据库,也是一个强大的内存型存储系统,但是它比传统的Memcached 更灵活,支持更多的数据类型,同时也可以持久化. 支持的数据类型 先 ...

  3. spring-boot mybatis配置

    接着我们的spring boot项目,spring boot如何使用mybatis访问数据库呢? 个人习惯使用mapper接口和xml配置sql,从pom.xml入手 1.1 添加依赖 <dep ...

  4. MongoDB系列----查

    开启查询: db.getMongo().setSlaveOk() 查版本: db.servion(); db.serverBuildInfo(); db.serverStatus().storageE ...

  5. 使用Apache JMeter对SQL Server、Mysql、Oracle压力测试(一)

    前段时间面试被问到了数据库方面的知识:比如选择什么样的数据库,如何优化,怎么加索引,于是想到了自己动手测试一下常用数据库的性能: 第一步,下载好JMeter之后打开运行.话说这个JMeter打开还真是 ...

  6. #WEB安全基础 : HTTP协议 | 0x11 HTTP的分块传输模块

    HTTP通信中,请求的编码实体资源没全部传输完成之前,浏览器无法显示页面,所以传输大容器数据时,把数据分块,能让浏览器逐步显示页面,这就叫分块传输模块 请看分块传输的流程图 每一块都会用十六进制来标记 ...

  7. OpenGL入门之入门

    programs on the GPU-------shader 顶点着色器-->形状(图元)装配-->几何着色器-->光栅化-->片段着色器-->测试与混合 图形渲染管 ...

  8. log4j2 标签解析

    根节点Configuration有两个属性:status和monitorinterval,有两个子节点:Appenders和Loggers. status用来指定log4j本身的打印日志的级别. mo ...

  9. sql where 里面判定要加 ' '

    WHERE year>=2010 and year<=2017 and indicator_code = 'SE.XPD.TOTL.GD.ZS'

  10. 【javascript】随机颜色

    调用该方法则会返回一个#xxx的rgb随机颜色 function color1(){ var sum=""; var shuzu2=['a','b','c','d','e','f' ...