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,我们将这个 ...
随机推荐
- 高效的Nginx
FastCGI是将CGI解释器进程保持在内存中并因此获得较高的性能.CGI解释器的反复加载是CGI性能低下的主要原因. 如果CGI解释器保持在内存中并接受FastCGI管理器的调度,则可以提供良好的性 ...
- Android:PopupWindow简单弹窗改进版
Android:PopupWindow简单弹窗 继续上一节的内容,改进一下,目标是点击菜单后把菜单收缩回去并且切换内容,我使用的是PopupWindow+RadioGroup public class ...
- 如何在Android应用程序中使用传感器模拟器SensorSimulator
原文地址; 如何在Android应用程序中使用传感器模拟器 - 移动平台应用软件开发技术 - 博客频道 - CSDN.NET http://blog.csdn.net/pku_android/arti ...
- HDU5087——Revenge of LIS II(BestCoder Round #16)
Revenge of LIS II Problem DescriptionIn computer science, the longest increasing subsequence problem ...
- Java API —— 反射
1.类加载器 1)类的加载 · 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化. · 加载 :就是 ...
- Java API ——Collection集合类 & Iterator接口
对象数组举例: 学生类: package itcast01; /** * Created by gao on 15-12-9. */ public class Student { private St ...
- thrift总结
定义: Apache Thrift是一个facebook建立的RPC框架,现在是一个Apache的顶级项目.Thrift允许通过一个跨语言的定义文件的方式定义数据类型和服务接口,[这个文件]作为[RP ...
- QTP公开课视频-持续更新中。。。
以下是视频的下载地址: http://pan.baidu.com/share/link?shareid=1760499709&uk=3711405498
- iosUITextField属性
@property UITextField *caption; caption = [[UITextField alloc] initWithFrame:CGRectMake(, self.frame ...
- 【POJ】1084 Square Destroyer
1. 题目描述由$n \times n, n \in [1, 5]$的正方形由$2 \times n \times (n+1)$根木棍组成,可能已经有些木棍被破坏,求至少还需破坏多少木根,可以使得不存 ...