bzoj 1014 [JSOI2008]火星人prefix(splay+hash)
【题目链接】
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)的更多相关文章
- BZOJ 1014: [JSOI2008]火星人prefix( splay + hash )
用splay维护序列, 二分+hash来判断LCQ.. #include<bits/stdc++.h> using namespace std; typedef unsigned long ...
- BZOJ 1014 [JSOI2008]火星人prefix (Splay + Hash + 二分)
1014: [JSOI2008]火星人prefix Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 8112 Solved: 2569[Submit] ...
- BZOJ 1014: [JSOI2008]火星人prefix [splay 二分+hash] 【未完】
1014: [JSOI2008]火星人prefix Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 6243 Solved: 2007[Submit] ...
- BZOJ 1014: [JSOI2008]火星人prefix Splay+二分
1014: [JSOI2008]火星人prefix 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=1014 Description 火星人 ...
- BZOJ 1014 [JSOI2008]火星人prefix (splay+二分答案+字符串hash)
题目大意:维护一个字符串,支持插入字符和替换字符的操作,以及查询该字符串两个后缀的最长公共前缀长度 乍一看以为是后缀数组,然而并没有可持久化后缀数组(雾) 看题解才知道这是一道splay题,首先要对s ...
- bzoj 1014 [JSOI2008]火星人prefix——splay+哈希
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1014 用splay维护字符串,每个点记录子树的哈希值,然后二分查询. 二分不是把两个点的哈希 ...
- BZOJ 1014 [JSOI2008]火星人prefix | Splay维护哈希值
题目: 题解: #include<cstdio> #include<algorithm> #include<cstring> typedef long long l ...
- bzoj 1014: [JSOI2008]火星人prefix hash && splay
1014: [JSOI2008]火星人prefix Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3154 Solved: 948[Submit][ ...
- 求帮看!!!!BZOJ 1014 [JSOI2008]火星人prefix
1014: [JSOI2008]火星人prefix Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 4164 Solved: 1277[Submit] ...
- 【BZOJ1014】[JSOI2008]火星人prefix Splay+hash
[BZOJ1014][JSOI2008]火星人prefix Description 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam,我们将这个 ...
随机推荐
- ios开发--27个提升效率的iOS开源库推荐
超长慎入列表: DZNEmptyDataSet(UI,空表格视图解算器) PDTSimpleCalendar(UI,drop-in日历组件) MagicalRecord(实施活跃记录模式的Core D ...
- 网上图书商城项目学习笔记-012BOOK模块查询2
一.分析 > 按图名查询(模糊)(分页)> 按作者查询(分页)> 按出版社查询(分页)> 按id查询> 多条件组合查询(分页) 二.代码 1.view层 (1)gj.js ...
- 创业草堂之二十二:创业公司C类官员的职位说明书
麻雀虽小,五脏俱全. 创业公司启航,三五十来个人.七八条枪,其中“C”字开头的官儿还真少不了 – CEO.CTO.COO.CFO.CMO.CIO.CCO.CLO.Chairman/Chairwoman ...
- 用于主题检测的临时日志(383b4f88-5dc7-4b08-a585-27104eb4ee7f - 3bfe001a-32de-4114-a6b4-4005b770f6d7)
这是一个未删除的临时日志.请手动删除它.(1e2a0af2-731b-4f82-9aa0-4e2d10ed7a1a - 3bfe001a-32de-4114-a6b4-4005b770f6d7)
- Java API —— Random类
1.Random类概述 此类用于产生随机数 如果用相同的种子创建两个 Random 实例,则对每个实例进行相同的方法调用序列,它们将生成并返回相同的数字序列. 2.构造 ...
- 2008年我买了一本书 书名叫“PHP 6”
上个星期天,我感觉应该整理一下我的书柜.于是,在书柜里,我发现了一本几乎完全忘记的书(我想不起来为什么要买它!):<PHP 6 – 快速简洁的Web开发> 这本书出版于2008年一月.而六 ...
- 从unity3d官网下载教程
http://unity3d.com/learn/tutorials/projects/tanks-tutorial 官网的教程提供的下载链接https://www.assetstore.unity3 ...
- devDependencies和dependencies的区别
我们在使用npm install 安装模块或插件的时候,有两种命令把他们写入到 package.json 文件里面去,比如: --save-dev --save 在 package.json 文件里面 ...
- POJ 1113 凸包模板题
上模板. #include <cstdio> #include <cstring> #include <iostream> #include <algorit ...
- jquery 字符串转json
这里考虑的都是服务器返回JSON形式的字符串的形式 代码如下: var data=" { root: [ {name:'1',value:'0'}, {name:'6101',value:' ...