【题目链接】

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. LR_问题_控制器不能使用定义的负载生成器

    问题描述 在controller 中设置了面向目标的方案后 执行提示 The target you defined cannot be reached.the LoadRunner Controlle ...

  2. java io知识点汇总FIle类

    1.路径分隔符问题: 因为java有跨平台行,而在windows和linux中的目录分隔符是不同的.windows是"\" 而linux是"/"  所以必须想办 ...

  3. js、javascript正则表达式验证身份证号码

    function isCardNo(card) { // 身份证号码为15位或者18位,15位时全为数字,18位前17位为数字,最后一位是校验位,可能为数字或字符X var reg = /(^\d{1 ...

  4. oracle索引,索引的建立、修改、删除

    索引,索引的建立.修改.删除 2007-10-05 13:29 来源: 作者: 网友评论 0 条 浏览次数 2986 索引索引是关系数据库中用于存放每一条记录的一种对象,主要目的是加快数据的读取速度和 ...

  5. 用net匹配并替换iOS标准的emoji表情符号

    using System; using System.Collections.Generic; using System.Linq; using System.Text; namespaceCommo ...

  6. pinyin4j使用示例

    pinyin4j的主页:http://pinyin4j.sourceforge.net/pinyin4j能够根据中文字符获取其对应的拼音,而且拼音的格式可以定制pinyin4j是一个支持将中文转换到拼 ...

  7. WEB-INF目录与META-INF目录的作用

    /WEB-INF/web.xml Web应用程序配置文件,描述了 servlet 和其他的应用组件配置及命名规则. /WEB-INF/classes/包含了站点所有用的 class 文件,包括 ser ...

  8. Jqgrid入门-操作表格的数据(二)

    上一篇中,Jqgrid已经可以从服务端获得数据,并显示在Grid表格中了.下面说一下,如何操作表格及其数据.           jqGrid有很多方法函数,用来操作数据或者操作Grid表格本身.jq ...

  9. libogg.so fro android编译方法

    在网站下载源代码http://www.xiph.org/downloads/ 解压然后打开cygwin配置 CXX=arm-linux-androideabi-g++.exe LD=arm-linux ...

  10. LeetCode Best Time to Buy and Sell Stock 买卖股票的最佳时机 (DP)

    题意:给定一个序列,第i个元素代表第i天这支股票的价格,问在最佳时机买入和卖出能赚多少钱?只买一次,且仅1股,假设本钱无限. 思路:要找一个最低价的时候买入,在最高价的时候卖出利润会最大.但是时间是不 ...