bzoj 1014 火星人prefix —— splay+hash
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1014
用 splay 维护字符串上不同位置的哈希值还是第一次...
具体就是每个节点作为位置被不断旋转,点上维护的哈希值就是此时它及其儿子这一段区间的哈希值;
要查询 LCQ,可以二分一个长度,然后把两端区间分别旋转到根,取出哈希值比较;
据说用模数会很慢,写自然溢出比较好;
因为忘记 rotate 最后要 pushup 而调了很久...注释里是另一种可以A的 rotate - splay 系列;
又加深了对 splay 的理解,它的节点表示位置关系...
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define mid ((l+r)>>1)
using namespace std;
typedef unsigned long long ll;
int const xn=1e5+,xm=;
int n,m,rt,fa[xm],c[xm][],siz[xm];
ll pw[xm],hsh[xm];
char s[xn],ch[xn];
void pushup(int x)
{
int ls=c[x][],rs=c[x][];
siz[x]=siz[ls]+siz[rs]+;
hsh[x]=hsh[ls]*pw[siz[rs]+]+(s[x]-'a'+)*pw[siz[rs]]+hsh[rs];
}
void rotate(int x,int &f)
{
int y=fa[x],z=fa[y],d=(c[y][]==x);
if(z)c[z][c[z][]==y]=x;
// if(y==f)f=x; else c[z][c[z][1]==y]=x;
fa[x]=z; fa[y]=x; fa[c[x][!d]]=y;
c[y][d]=c[x][!d]; c[x][!d]=y;
pushup(y); pushup(x);//!!!
}
void splay(int x,int f)//
{
while(fa[x]!=f)//
{
int y=fa[x],z=fa[y];
if(z!=f)//
{
if((c[y][]==x)^(c[z][]==y))rotate(x,f);
else rotate(y,f);
}
rotate(x,f);
}
if(!f)rt=x;
}
void build(int l,int r,int lst)
{
if(l>r)return;
if(l==r)hsh[l]=s[l]-'a'+,siz[l]=;
else build(l,mid-,mid),build(mid+,r,mid);
fa[mid]=lst; c[lst][mid>lst]=mid; pushup(mid);
}
int find(int x,int k)//找到 k 位置
{
while()
{
int p=c[x][],q=c[x][];
if(siz[p]+==k)return x;
else if(siz[p]+<k)x=q,k-=siz[p]+;
else x=p;
}
}
void insert(int pos,char d)
{
s[++n]=d; hsh[n]=d-'a'+;
int x=find(rt,pos+);//+1 因为有左右的'a'
splay(x,); x=find(rt,pos+); splay(x,rt);//
// splay(x,rt); x=find(rt,pos+2); splay(x,c[rt][1]);
c[x][]=n; siz[n]=; fa[n]=x;
pushup(x); pushup(rt);
}
void change(int pos,char d)
{
int x=find(rt,pos+);
splay(x,);//
// splay(x,rt);
s[x]=d; pushup(x);
}
bool ck(int l,int r,int k)
{
ll h1=,h2=;
// int x=find(rt,l); splay(x,rt);//
// x=find(rt,l+k+1); splay(x,c[rt][1]);
// x=c[rt][1];//
int x=find(rt,l); splay(x,);
x=find(rt,l+k+); splay(x,rt);
h1=hsh[c[x][]];
// x=find(rt,r); splay(x,rt);//
// x=find(rt,r+k+1); splay(x,c[rt][1]);
// x=c[rt][1];//
x=find(rt,r); splay(x,);
x=find(rt,r+k+); splay(x,rt);
h2=hsh[c[x][]];
return h1==h2;
}
int query(int x,int l,int r)
{
int ll=,rr=n--max(l,r)+,ret=;
while(ll<=rr)
{
int md=((ll+rr)>>);
if(ck(l,r,md))ret=md,ll=md+;
else rr=md-;
}
return ret;
}
void init()
{
n=strlen(s+); pw[]=;
for(int i=;i<=xm-;i++)pw[i]=pw[i-]*;
s[]=s[n+]='a';
build(,n+,); n=n+; rt=(n+)/;//
}
int main()
{
scanf("%s",s+); init();
scanf("%d",&m);
for(int i=,x,y;i<=m;i++)
{
scanf("%s%d",ch,&x);
if(ch[]=='I')scanf("%s",ch),insert(x,ch[]);
if(ch[]=='R')scanf("%s",ch),change(x,ch[]);
if(ch[]=='Q')scanf("%d",&y),printf("%d\n",query(rt,x,y));
}
return ;
}
bzoj 1014 火星人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] ...
- 【BZOJ1014】[JSOI2008]火星人prefix Splay+hash
[BZOJ1014][JSOI2008]火星人prefix Description 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam,我们将这个 ...
- 【bzoj1014】[JSOI2008]火星人prefix Splay+Hash+二分
题目描述 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam,我们将这个字符串的各个字符予以标号:序号: 1 2 3 4 5 6 7 8 9 10 ...
- $bzoj1014-JSOI2008$ 火星人$prefix$ $splay$ $hash$
题面描述 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:\(madamimadam\),我们将这个字符串的各个字符予以标号: 序号 1 2 3 4 5 6 7 8 ...
- BZOJ 1014 火星人prefix
Description 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam,我们将这个字符串的各个字符予以标号:序号: 1 2 3 4 5 6 7 ...
- [BZOJ]1014 火星人prefix(JSOI2008)
一边听省队dalao讲课一边做题真TM刺激. BZOJ的discuss简直就是题面plus.大样例.SuperHINT.dalao题解的结合体. Description 火星人最近研究了一种操作:求一 ...
- bzoj 1014 火星人prefix - 链表 - 分块
Description 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam,我们将这个字符串的各个字符予以标号:序号: 1 2 3 4 5 6 7 ...
- bzoj1014: [JSOI2008]火星人prefix splay+hash+二分
Description 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam,我们将这个字符串的各个字符予以标号:序号: 1 2 3 4 5 6 7 ...
随机推荐
- php实现设计模式————单例模式
php实现设计模式————单例模式 什么是单例模式 为什么要使用单例模式 php中有哪些方式实现新建一个对象实例 如何阻止这种实例化实现理想的单例模式 代码实现 什么是单例模式 为什么要使用单例模式 ...
- codeforces #299 div 2
(总算是5题都做完了- -) 暂时做了4题,先放一下有时间做最后一题(当然如果我真的能做出的话...)(看了大神的代码总算是理解了E题,做完发现也没那么难,果然想出一个思路的过程对于我这种弱渣来说还是 ...
- 多边形之战(bzoj 2927)
Description 多边形之战是一个双人游戏.游戏在一个有n个顶点的凸多边形上进行,这个凸多边形的n-3条对角线将多边形分成n-2个三角形,这n-3条对角线在多边形的顶点相交.三角形中的一个被染成 ...
- 【ZJOI2017 Round1练习】D2T2 iqtest(排列组合)
题意: 思路: 根据欧拉定理,a^(phi(n)-1)为a mod n的逆元 ..]of longint; s,ans,x,mo,k,phi,tmp:int64; i,m,n,j:longint; f ...
- Eval 和 Bind 的区别
原文发布时间为:2008-10-20 -- 来源于本人的百度文章 [由搬家工具导入] 据绑定表达式包含在 <%# 和 %> 分隔符之内,并使用 Eval 和 Bind 函数。 Eval 函 ...
- MySQL Slow Log慢日志分析【转】
如果你的MySQL出现了性能问题,第一个需要“诊断”的就是slow log(慢日志)了. slow log文件很小,使用more less等命令就足够了.如果slow log很大怎么办?这里介绍MyS ...
- Spring mvc之SimpleUrlHandlerMapping
1.配置文件如下 <bean id="method" class="com.xx.controller.xxxController" scope=&quo ...
- Atom安装Markdown编辑器
1.安装插件 2.打开/关闭实时渲染: [Ctrl]+[Shift]+[M] 3.[增强]安装同步滚动插件(markdown-scroll-sync) 4.[增强]安装代码增强插件(language- ...
- Maven新建webapp项目报错Could not resolve artifact org.apache.maven.archetypes:maven-archetype-webapp:pom:RELEASE
Windows-Preferences 在搜索框输入maven,点击下面的Archetypes--->Add Remote Catalog... 对应输入 http://repo1.maven. ...
- 【神乎其神】这些EXCEL技巧,太神奇了,赶紧收藏!
转:http://learning.sohu.com/20160215/n437421658.shtml