【题目链接】

http://www.lydsy.com/JudgeOnline/problem.php?id=1014

【题意】

给定一个字符串,要求提供修改一个字符,插入一个字符,查询两个后缀LCP的功能。

【思路】

  splay维护字符串的哈希值。因为要提供区间,splay采用先查找后调整至根的写法。

一个结点的hash值为:

ch[0]->h * X^(ch[1]->s+1)+v * X^(ch[1]->s)+ch[1]->h

    对于一个询问每次二分长度,提取区间后比较hash值即可。

需要注意的是splay要提前在区间的左右两边各加上一个节点,不然会调用到null。

ull自然溢出相当于模2^64。

【代码】

 #include<set>
#include<cmath>
#include<queue>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define trav(u,i) for(int i=front[u];i;i=e[i].nxt)
#define FOR(a,b,c) for(int a=(b);a<=(c);a++)
using namespace std; typedef long long ll;
typedef unsigned long long ull;
const int N = 5e5+;
const int X = ; ll read() {
char c=getchar();
ll f=,x=;
while(!isdigit(c)) {
if(c=='-') f=-; c=getchar();
}
while(isdigit(c))
x=x*+c-'',c=getchar();
return x*f;
} char s[N];
int n,q;
ull powx[N]; struct Node* null;
struct Node {
int s,v; ull h;
Node* ch[];
int cmp(int k) {
if(k==ch[]->s+) return -;
return k<=ch[]->s? :;
}
void init(int x) {
v=h=x; s=;
ch[]=ch[]=null;
}
void maintain() {
s=ch[]->s+ch[]->s+;
h=ch[]->h*powx[ch[]->s+]+v*powx[ch[]->s]+ch[]->h;
}
} *root,nodepool[N]; int nodesz=; void rot(Node* &o,int d) {
Node* k=o->ch[d^]; o->ch[d^]=k->ch[d]; k->ch[d]=o;
o->maintain(),k->maintain(); o=k;
}
void splay(Node*& o,int k) {
int d=o->cmp(k);
if(d==) k-=o->ch[]->s+;
if(d!=-) {
Node* p=o->ch[d];
int d2=p->cmp(k),k2=(d2==?k:k-p->ch[]->s-);
if(d2!=-) {
splay(p->ch[d2],k2);
if(d==d2) rot(o,d^); else rot(o->ch[d],d);
}
rot(o,d^);
}
}
//return range (l,r]
//加过点后 s[l,r]=range(l,r+1)
Node*& range(int l,int r) {
splay(root,l);
splay(root->ch[],r-l+);
return root->ch[]->ch[];
} Node* build(int l,int r)
{
if(r<l) return null;
int mid=l+r>>;
Node* o=&nodepool[++nodesz];
o->init(s[mid]-'a'+);
o->ch[]=build(l,mid-);
o->ch[]=build(mid+,r);
o->maintain();
return o;
}
void insert(int p,int v)
{
splay(root,p+);
Node* o=&nodepool[++nodesz];
o->init(v);
o->ch[]=root->ch[]; o->ch[]=null;
o->maintain();
root->ch[]=o; root->maintain();
}
void change(int p,int v)
{
splay(root,p);
root->v=v;
root->maintain();
} int main()
{
//freopen("in.in","r",stdin);
//freopen("out.out","w",stdout);
null=new Node();
scanf("%s",s+);
int n=strlen(s+);
s[]='z'+; s[++n]='z'+; s[n+]='\0';
scanf("%d",&q);
powx[]=;
FOR(i,,n+q) powx[i]=powx[i-]*X;
root=build(,n);
while(q--) {
char op[],val[];
int x,y;
scanf("%s%d",op,&x);
if(op[]=='R') {
scanf("%s",val);
change(x+,val[]-'a'+);
} else
if(op[]=='I') {
scanf("%s",val);
insert(x+,val[]-'a'+);
} else {
scanf("%d",&y);
int len=root->s,L=,R=;
R=min(len-y-,len-x-);
while(L<R) {
int M=L+(R-L+)/;
ull H=range(x,x+M)->h;
H-=range(y,y+M)->h;
if(!H) L=M; else R=M-;
}
printf("%d\n",L);
} }
return ;
}

bzoj 1014 [JSOI2008]火星人prefix(splay+hash)的更多相关文章

  1. BZOJ 1014: [JSOI2008]火星人prefix( splay + hash )

    用splay维护序列, 二分+hash来判断LCQ.. #include<bits/stdc++.h> using namespace std; typedef unsigned long ...

  2. BZOJ 1014 [JSOI2008]火星人prefix (Splay + Hash + 二分)

    1014: [JSOI2008]火星人prefix Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 8112  Solved: 2569[Submit] ...

  3. BZOJ 1014: [JSOI2008]火星人prefix [splay 二分+hash] 【未完】

    1014: [JSOI2008]火星人prefix Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 6243  Solved: 2007[Submit] ...

  4. BZOJ 1014: [JSOI2008]火星人prefix Splay+二分

    1014: [JSOI2008]火星人prefix 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=1014 Description 火星人 ...

  5. BZOJ 1014 [JSOI2008]火星人prefix (splay+二分答案+字符串hash)

    题目大意:维护一个字符串,支持插入字符和替换字符的操作,以及查询该字符串两个后缀的最长公共前缀长度 乍一看以为是后缀数组,然而并没有可持久化后缀数组(雾) 看题解才知道这是一道splay题,首先要对s ...

  6. bzoj 1014 [JSOI2008]火星人prefix——splay+哈希

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1014 用splay维护字符串,每个点记录子树的哈希值,然后二分查询. 二分不是把两个点的哈希 ...

  7. BZOJ 1014 [JSOI2008]火星人prefix | Splay维护哈希值

    题目: 题解: #include<cstdio> #include<algorithm> #include<cstring> typedef long long l ...

  8. bzoj 1014: [JSOI2008]火星人prefix hash && splay

    1014: [JSOI2008]火星人prefix Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3154  Solved: 948[Submit][ ...

  9. 求帮看!!!!BZOJ 1014 [JSOI2008]火星人prefix

    1014: [JSOI2008]火星人prefix Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 4164  Solved: 1277[Submit] ...

  10. 【BZOJ1014】[JSOI2008]火星人prefix Splay+hash

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

随机推荐

  1. ios开发--27个提升效率的iOS开源库推荐

    超长慎入列表: DZNEmptyDataSet(UI,空表格视图解算器) PDTSimpleCalendar(UI,drop-in日历组件) MagicalRecord(实施活跃记录模式的Core D ...

  2. 网上图书商城项目学习笔记-012BOOK模块查询2

    一.分析 > 按图名查询(模糊)(分页)> 按作者查询(分页)> 按出版社查询(分页)> 按id查询> 多条件组合查询(分页) 二.代码 1.view层 (1)gj.js ...

  3. 创业草堂之二十二:创业公司C类官员的职位说明书

    麻雀虽小,五脏俱全. 创业公司启航,三五十来个人.七八条枪,其中“C”字开头的官儿还真少不了 – CEO.CTO.COO.CFO.CMO.CIO.CCO.CLO.Chairman/Chairwoman ...

  4. 用于主题检测的临时日志(383b4f88-5dc7-4b08-a585-27104eb4ee7f - 3bfe001a-32de-4114-a6b4-4005b770f6d7)

    这是一个未删除的临时日志.请手动删除它.(1e2a0af2-731b-4f82-9aa0-4e2d10ed7a1a - 3bfe001a-32de-4114-a6b4-4005b770f6d7)

  5. Java API —— Random类

    1.Random类概述         此类用于产生随机数         如果用相同的种子创建两个 Random 实例,则对每个实例进行相同的方法调用序列,它们将生成并返回相同的数字序列. 2.构造 ...

  6. 2008年我买了一本书 书名叫“PHP 6”

    上个星期天,我感觉应该整理一下我的书柜.于是,在书柜里,我发现了一本几乎完全忘记的书(我想不起来为什么要买它!):<PHP 6 – 快速简洁的Web开发> 这本书出版于2008年一月.而六 ...

  7. 从unity3d官网下载教程

    http://unity3d.com/learn/tutorials/projects/tanks-tutorial 官网的教程提供的下载链接https://www.assetstore.unity3 ...

  8. devDependencies和dependencies的区别

    我们在使用npm install 安装模块或插件的时候,有两种命令把他们写入到 package.json 文件里面去,比如: --save-dev --save 在 package.json 文件里面 ...

  9. POJ 1113 凸包模板题

    上模板. #include <cstdio> #include <cstring> #include <iostream> #include <algorit ...

  10. jquery 字符串转json

    这里考虑的都是服务器返回JSON形式的字符串的形式 代码如下: var data=" { root: [ {name:'1',value:'0'}, {name:'6101',value:' ...