UVA11996 Jewel Magic
思路
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的更多相关文章
- Jewel Magic UVA - 11996 || bzoj1014: [JSOI2008]火星人prefix
Jewel Magic UVA - 11996 这是一道用splay/非旋treap做的题(这里用的是非旋treap) 1/2/3是splay/非旋treap的常规操作.对于操作4,可以用哈希法求LC ...
- UVa 11996 Jewel Magic (splay + Hash + 二分)
题意:给定一个长度为n的01串,你的任务是依次执行如表所示的m条指令: 1 p c 在第p个字符后插入字符,p = 0表示在整个字符串之前插入2 p 删除第p个字符,后面的字符往前移3 p1 p2反转 ...
- UVA - 11996 Jewel Magic (Treap+二分哈希)
维护一个01序列,一共四种操作: 1.插入一个数 2.删除一个数 3.反转一个区间 4.查询两个后缀的LCP 用Splay或者Treap都可以做,维护哈希值,二分求LCP即可. 注意反转序列的时候序列 ...
- UVA 11996 Jewel Magic —— splay、序列的分裂与合并、LCP的哈希算法
#include <cstdio> #include <cstdlib> #include <iostream> #include <algorithm> ...
- Ceph Jewel 10.2.3 环境部署
Ceph 测试环境部署 本文档内容概要 测试环境ceph集群部署规划 测试环境ceph集群部署过程及块设备使用流程 mon节点扩容及osd节点扩容方法 常见问题及解决方法 由于暂时没有用到对象存储,所 ...
- 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/ ...
- 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.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 ...
- Python魔术方法-Magic Method
介绍 在Python中,所有以"__"双下划线包起来的方法,都统称为"Magic Method",例如类的初始化方法 __init__ ,Python中所有的魔 ...
随机推荐
- NodeJS笔记(六)-Express HTTP服务器启动后如何关闭
npm start启动网站,提示“3000”端口已经被使用的问题 nodejs WEB服务器并不随着cmd的关闭而终止 查看任务管理器可以看到nodejs的启动进程 可以手动关闭 如果是一直处于cmd ...
- Django之JWT理解及简单应用
Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(S ...
- VM中centos设置子网内虚拟机ip
,首先应该设置vm的网络,打开编辑->虚拟网络编辑器,弹出框及具体设置如下图 2,选中相应的虚拟机,右键设置,并设置相应的选项,具体设置如下图 3.设置完成后,打开虚拟机,等待虚拟机启动后,输入 ...
- ADB——adb devices unauthorized
我们只有在手机打开USB调试,并且允许电脑对其进行调试的前提下才可以用ADB进行自动化操作手机,如果出现unauthorized提示的话就是说明手机没有允许电脑对其调试 这个时候通常手机回弹出允许调试 ...
- canal 代码阅读
涉及到有边界队列,无边界队列.poolSize.corePoolSize.maximumPoolSize 三者参数含义 If there are more than corePoolSize but ...
- python使用telnetlib
python使用telnetlib 1 前言 目前,本篇仅记录前段时间搜索得到的关于python使用Telnet的技术博客,由于受领新任务,未进一步验证和深入研究与应用. 参考链接: python官网 ...
- OO第二单元总结(多线程的电梯调度)
经过第一单元作业的训练,在做第二单元的作业的时候,要更加的有条理.但是第二次作业多线程的运行,带来了更多的运行的不确定性.呈现出来就是程序会出现由于线程安全问题带来的不可复现的bug.本单元的作业也让 ...
- Windows 10安装Docker 步骤及顺序
最近在工作中,重新安装Docker时,遇到了一点坑,故将自己解决经验分享一下~ Hardware assisted virtualization and data execution protecti ...
- Mysql事务隔离级别学习
这篇文章主要谈谈Mysql事务隔离级别的区别,以及自己的一些感受. 自己一直以来没搞懂“可重复读”和可提交读“两者之间的区别,通过此次的实践,清楚了两者之间的区别.废话不说,先上图看看这几个事务隔离级 ...
- 装PIL库
pip install Pillow -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com