bzoj 1014 splay
首先我们可以用splay来维护这个字符串,那么对于某两个位置的lcp,维护每个节点的子树的hash,然后二分判断就好了。
/**************************************************************
Problem: 1014
User: BLADEVIL
Language: C++
Result: Accepted
Time:4468 ms
Memory:3640 kb
****************************************************************/
//By BLADEVIL
#include <cstdio>
#include <cstring>
#include <algorithm>
#define maxn 100010
using namespace std;
char s[maxn];
int fac[maxn],key[maxn],num,rot,son[maxn][],father[maxn],size[maxn],hash[maxn];
void update(int x) {
if (!x) return ;
hash[x]=hash[son[x][]]+(key[x]+hash[son[x][]]*)*fac[size[son[x][]]];
size[x]=size[son[x][]]+size[son[x][]]+;
}
int build(int l,int r) {
int mid=l+r>>,left=,right=;
if (mid<r) right=build(mid+,r);
if (mid>l) left=build(l,mid-);
father[left]=father[right]=mid;
son[mid][]=left; son[mid][]=right;
update(mid);
return mid;
}
void rotate(int x,int &rot) {
int y=father[x],z=father[y];
int p=(son[y][]==x),q=p^;
if (y==rot) rot=x; else if (son[z][]==y) son[z][]=x; else son[z][]=x;
father[x]=z; father[y]=x; father[son[x][q]]=y;
son[y][p]=son[x][q]; son[x][q]=y;
update(y);
}
void splay(int x,int &rot) {
while (x!=rot) {
int y=father[x],z=father[y];
if (y!=rot)
if ((son[y][]==x)^(son[z][]==y)) rotate(x,rot); else rotate(y,rot);
rotate(x,rot);
}
update(x);
}
int find(int x) {
int t=rot;
while () {
if (size[son[t][]]+==x) return t; else
if (size[son[t][]]+>x) t=son[t][]; else
if (size[son[t][]]+<x) x-=size[son[t][]]+,t=son[t][];
}
}
bool judge(int x,int y,int len) {
if (len==) return key[find(x+)]==key[find(y+)];
int p=find(x),q=find(x+len+);
splay(p,rot); splay(q,son[rot][]);
int a1=hash[son[q][]];
p=find(y); q=find(y+len+);
splay(p,rot); splay(q,son[rot][]);
int a2=hash[son[q][]];
return a1==a2;
}
int main() {
scanf("%s",&s); num=strlen(s);
fac[]=; for (int i=;i<maxn;i++) fac[i]=fac[i-]*;
for (int i=;i<=num+;i++) key[i]=s[i-]-'a'+; num+=;
rot=build(,num);
int task; scanf("%d",&task);
while (task--) {
int x,y;
scanf("%s",&s);
if (s[]=='Q') {
scanf("%d%d",&x,&y);
if (x>y) swap(x,y);
int l=,r=num-y-,mid,ans=;
while (l<=r) {
mid=l+r>>;
if (judge(x,y,mid)) ans=mid, l=mid+; else r=mid-;
}
printf("%d\n",ans);
} else
if (s[]=='R') {
scanf("%d%s",&x,&s);
int p=find(x+);
key[p]=s[]-'a'+;
splay(p,rot);
} else
if (s[]=='I') {
scanf("%d%s",&x,&s);
key[++num]=s[]-'a'+;
int p=find(x+); splay(p,rot);
int q=find(x+); splay(q,son[rot][]);
father[num]=q; son[q][]=num;
splay(num,rot);
}
}
return ;
}
bzoj 1014 splay的更多相关文章
- bzoj 1014 splay维护hash值
被后缀三人组虐了一下午,写道水题愉悦身心. 题很裸,求lcq时二分下答案就行了,写的不优美会被卡时. (写题时精神恍惚,不知不觉写了快两百行...竟然调都没调就A了...我还是继续看后缀自动机吧... ...
- [BZOJ 1014] [JSOI2008] 火星人prefix 【Splay + Hash】
题目链接:BZOJ - 1014 题目分析 求两个串的 LCP ,一种常见的方法就是 二分+Hash,对于一个二分的长度 l,如果两个串的长度为 l 的前缀的Hash相等,就认为他们相等. 这里有修改 ...
- BZOJ 1014 火星人 | 平衡树维护哈希
BZOJ 1014 火星人 题意 有一个字符串,三中操作:在某位置后面插入一个字符.修改某位置的字符.询问两个后缀的最长公共前缀. 题解 看到网上的dalao们都说这道题是平衡树,我就很懵x--平衡树 ...
- 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)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1014 [题意] 给定一个字符串,要求提供修改一个字符,插入一个字符,查询两个后缀LCP ...
- 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( 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] ...
随机推荐
- anaconda安装不存在的包
Anaconda作为一个工具包集成管理工具,下载python工具包是很方便的,直接敲: conda install package_name 1 但是有时候安装一个工具包(如skimage)的时候,在 ...
- Git命令基本操作
本文从以下九个方面,介绍Git命令的基本操作: 一. Git安装 二. Git基本配置 三. 创建Git仓库 四. 获得Git仓库 五. 提交更新 六. 提交历史查看 七. 远程仓库 八. 打Tags ...
- Filezilla 绿色版 禁止升级 能用。
FileZilla还是挺好用的,但是如果钟情于 绿色版的话,肯定首选是 免安装绿色版.但是呢,能找到的所谓的免升级 绿色版,都不能用.只要是打开软件了,就会在你还没有设置更新之前,就已经升级号了.并且 ...
- 图像检测算法Halcon 10的使用
安装完成HALCON之后,在VS项目中添加动态链接库配置项目,并修改此项目属性的包含目录.库目录和链接器.
- [CLR via C#]值类型的装箱和拆箱
我们先来看一个示例代码: namespace ConsoleApplication1 { class Program { static void Main(string[] args) { Array ...
- C#中的反射和扩展方法的运用
前段时间做了一个练手的小项目,采用的是三层架构,也就是Models,IDAL,DAL,BLL 和 Web , 在DAL层中各个类中有一个方法比较常用,那就是 RowToClass ,顾名思义,也就是将 ...
- [洛谷P4781]【模板】拉格朗日插值
题目大意:给你$n(n\leqslant2000)$个点,要你求$n-1$次经过这$n$个点的多项式在$k$处的值 题解:$Lagrange$插值:$$f_x=\sum\limits_{i=1}^ky ...
- BZOJ1492:[NOI2007]货币兑换——题解
http://www.lydsy.com/JudgeOnline/problem.php?id=1492 (题目描述太长了不粘贴了……) ……………………………………………………… 我 是自己做的 抄 ...
- 2 Advanced Read/Write Splitting with PHP’s MySQLnd
原文地址需FQ才能看 https://blog.engineyard.com/2014/advanced-read-write-splitting-with-phps-mysqlnd In part ...
- 5028: 小Z的加油店(线段树)
NOI2012魔幻棋盘弱化版 gcd(a,b,c,d,e)=gcd(a,b-a,c-b,d-c,e-d) 然后就可以把区间修改变成差分后的点修了. 用BIT维护原序列,线段树维护区间gcd,支持点修区 ...