思路:插入、修改操作是splay的模型,然后询问的话就可以二分答案,然后再用splay去判,关键就在于怎么去判断。

可以用字符串hash,splay每个节点维护一个hash域,然后就可以定义一个进制去hash即可二分判断,hash值让其自然溢出即可。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#define maxn 100005
#define p 37 int n,m;
unsigned int power[maxn];
char s[maxn],t[5]; struct splay_tree{
int ch[maxn][2],fa[maxn],note[maxn],size[maxn],root,tot;
unsigned int hash[maxn],val[maxn];
void update(int x){
if (!x) return;int ls=ch[x][0],rs=ch[x][1];
size[x]=size[ls]+size[rs]+1;
hash[x]=hash[ls]*power[size[rs]+1]+val[x]*power[size[rs]]+hash[rs];
}
void newnode(int &x,int v,int bo){val[x=++tot]=v,note[x]=bo;}
void build(int &x,int l,int r,int bo){
if (l>r) return;int mid=(l+r)>>1;
newnode(x,(mid!=0&&mid!=n+1)?s[mid]-'a':0,bo);
build(ch[x][0],l,mid-1,0),build(ch[x][1],mid+1,r,1);
fa[ch[x][0]]=fa[ch[x][1]]=x;
update(x);
}
void rotate(int x){
int y=fa[x],z=fa[y],bo=note[x],bo1=note[y];
ch[y][bo]=ch[x][bo^1],fa[ch[x][bo^1]]=y;
ch[x][bo^1]=y,fa[y]=x;
fa[x]=z;if (bo1!=2) ch[z][bo1]=x;
note[x]=bo1,note[y]=bo^1,note[ch[y][bo]]=bo;
update(y);
}
void splay(int x){
while (note[x]!=2){
if (note[x]==note[fa[x]]) rotate(fa[x]);
rotate(x);
}
root=x,update(x);
}
int find(int pos){
int x=root;
while (1){
if (size[ch[x][0]]+1==pos) return splay(x),x;
else if (size[ch[x][0]]>=pos) x=ch[x][0];
else pos-=size[ch[x][0]]+1,x=ch[x][1];
}
}
int suc(int x){x=ch[x][1];while (ch[x][0]) x=ch[x][0];return x;}
void insert(int x,int v){
splay(x);int y=suc(x),z;newnode(z,v,0);
fa[ch[x][1]]=0,note[ch[x][1]]=2,splay(y);
fa[y]=x,note[y]=1,ch[x][1]=y;
fa[z]=y,ch[y][0]=z,splay(z);
}
void change(int x,int v){val[x]=v;splay(x);}
unsigned int gethash(int l,int len){
int r=l+len-1,x=find(l),y=find(r+2);
splay(x),fa[ch[x][1]]=0,note[ch[x][1]]=2,splay(y);
note[y]=1,fa[y]=x,ch[x][1]=y;
unsigned int ans=hash[ch[y][0]];
return splay(y),ans;
}
bool check(int x,int y,int len){return gethash(x,len)==gethash(y,len);}
}S; void solve(int x,int y){
int l=1,r=min(S.tot-x-1,S.tot-y-1),ans=0;
while (l<=r){
int mid=(l+r)>>1;
if (S.check(x,y,mid)) l=mid+1,ans=mid;
else r=mid-1;
}
printf("%d\n",ans);
} int main(){
scanf("%s",s+1),scanf("%d",&m);power[0]=1,n=strlen(s+1);
for (int i=1;i<=100001;i++) power[i]=power[i-1]*p;
S.build(S.root,0,n+1,2);
while (m--){
int x,y;scanf("%s",t+1);
if (t[1]=='I') scanf("%d%s",&x,t+1),S.insert(S.find(x+1),t[1]-'a');
else if (t[1]=='R') scanf("%d%s",&x,t+1),S.change(S.find(x+1),t[1]-'a');
else scanf("%d%d",&x,&y),solve(x,y);
}
return 0;
}

bzoj1014:[JSOI2008]火星人prefix的更多相关文章

  1. [BZOJ1014][JSOI2008]火星人prefix

    [BZOJ1014][JSOI2008]火星人prefix 试题描述 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam,我们将这个字符串的各个字 ...

  2. BZOJ1014 JSOI2008 火星人prefix 【非旋转Treap】*

    BZOJ1014 JSOI2008 火星人prefix Description 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam,我们将这个字符 ...

  3. 2018.06.28 BZOJ1014 [JSOI2008]火星人prefix(非旋treap+hash)

    [JSOI2008]火星人prefix Time Limit: 10 Sec Memory Limit: 162 MB Submit: 8951 Solved: 2860 Description 火星 ...

  4. bzoj千题计划106:bzoj1014 [JSOI2008]火星人prefix

    http://www.lydsy.com/JudgeOnline/problem.php?id=1014 两个后缀的最长公共前缀:二分+hash 带修改带插入:splay维护 #include< ...

  5. [BZOJ1014] [JSOI2008] 火星人prefix (splay & 二分答案)

    Description 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam,我们将这个字符串的各个字符予以标号:序号: 1 2 3 4 5 6 7 ...

  6. bzoj1014: [JSOI2008]火星人prefix splay+hash+二分

    Description 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam,我们将这个字符串的各个字符予以标号:序号: 1 2 3 4 5 6 7 ...

  7. [bzoj1014](JSOI2008)火星人 prefix (Splay维护哈希)

    Description 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀. 比方说,有这样一个字符串:madamimadam,我们将这个字符串的各个字符予以标号:序号: 1 2 3 4 5 6 ...

  8. BZOJ1014[JSOI2008]火星人prefix(splay维护hash)

    Description 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam,我们将这个字符串的各个字符予以标号:序号: 1 2 3 4 5 6 7 ...

  9. BZOJ1014: [JSOI2008]火星人prefix(splay 二分 hash)

    题意 题目链接 Sol 一眼splay + 二分hash,不过区间splay怎么写来着呀 试着写了两个小时发现死活不对 看了一下yyb的代码发现自己根本就不会splay.... // luogu-ju ...

  10. bzoj1014: [JSOI2008]火星人prefix(splay+hash+二分)

    题目大意:一个字符串三个操作:①求两个后缀的LCP②插入一个字符③修改一个字符. 前几天刚学了hash+二分求lcp,就看到这题. 原来splay还能这么用?!原来splay模板这么好写?我以前写的s ...

随机推荐

  1. HW4.39

    public class Solution { public static void main(String[] args) { double sum; double baseSalary = 500 ...

  2. (qsf文件 、 tcl文件 和 csv(txt)文件的区别) FPGA管脚分配文件保存、导入导出方法

    FPGA管脚分配文件保存方法 使用别人的工程时,有时找不到他的管脚文件,但可以把他已经绑定好的管脚保存下来,输出到文件里. 方法一: 查看引脚绑定情况,quartus -> assignment ...

  3. C#使用参数数组

    重载,是指在相同的作用域内,声明多个同名的方法.用以对不同类型或数量的参数的参数执行相同的操作.比如,可以求两个或者三个 int类型数中的最大值,我们可以编写这样的方法实现: class Util { ...

  4. C++或者C#中如何拿到一个窗口的标题

    博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:C++或者C#中如何拿到一个窗口的标题.

  5. Asp.net Mvc 自定义Session (一),

    大家都知道用系统默认的session 会存在这样的问题 如果用户过多的话 session 会自动消亡,而且不能支持分布式和集群. 这系列博客主要讲解  怎样 解决用户过多的session自动消亡,和分 ...

  6. android系统架构图

    android的系统架构和其操作系统一样,采用了分层的架构.从架构图看,android分为四个层,从高层到低层分别是应用程序层.应用程序框架层.系统运行库层和Linux核心层. 1.应用程序 Andr ...

  7. MySQL——索引与优化

    http://www.cnblogs.com/hustcat/archive/2009/10/28/1591648.html 写在前面:索引对查询的速度有着至关重要的影响,理解索引也是进行数据库性能调 ...

  8. _blank开新窗体不符合标准?

    我们要在新窗体中打开链接通常的做法是在链接后面加target="_blank",我们採用过渡型的DOCTYPE(xh tml1-transitional. dtd)时没有问题,可是 ...

  9. Mac OS X 如何设置默认浏览器

    有时候我们不希望在 Mac 中点击任何连接都打开的是 Safari,这需要修改默认浏览器设置,在 Mac OS X 中如何设置默认浏览器呢? 打开 Safari 的偏好设置,在「通用」选项卡中有「默认 ...

  10. 基于DOM的XSS注入漏洞简单解析

    基于DOM的XSS注入漏洞简单解析http://automationqa.com/forum.php?mod=viewthread&tid=2956&fromuid=21