题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1014

用splay维护字符串,每个点记录子树的哈希值,然后二分查询。

二分不是把两个点的哈希值拿出来二分!因为取模了所以不能还原;因为splay维护了字符串,所以二分答案后把对应一段转出来看看哈希值一不一样就行了。

如果一开始不是用给出的序列直接建一个树(就是递归 l,mid-1 和 mid+1,r 那样的),而是像我一开始一样一个一个往进插入的话,不知为何过不了呢。

有些卡时间。据说%mod会T,于是用 unsigned long long 自然溢出。

用 nxt 找后继的时候要先把对象旋转到根才行。

幂也要预处理以防超时。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#define ll unsigned long long
using namespace std;
const int N=2e5+,base=;
int n,tot,c[N][],fa[N],rt,siz[N];
ll val[N],sm[N],pw[N];
char ch[N];
int init()
{
pw[]=;
for(int i=;i<=N-;i++) pw[i]=pw[i-]*base;
}
void pshp(int cr)
{
int ls=c[cr][],rs=c[cr][];
siz[cr]=siz[ls]+siz[rs]+; val[cr]=(val[rs]*base+sm[cr])*pw[siz[ls]]+val[ls];
}
void rotate(int x,int &k)
{
int y=fa[x],z=fa[y];
if(y==k) k=x;
else c[z][y==c[z][]]=x;
int d=(x==c[y][]);
fa[x]=z; fa[y]=x; fa[c[x][!d]]=y;
c[y][d]=c[x][!d]; c[x][!d]=y;
pshp(y); pshp(x);
}
void splay(int x,int &k)
{
while(x!=k)
{
int y=fa[x],z=fa[y];
if(y!=k)
{
if((x==c[y][])^(y==c[z][]))
rotate(x,k);
else rotate(y,k);
}
rotate(x,k);
}
}
int find(int p)
{
int cr=rt;
while(cr)
{
if(siz[c[cr][]]+==p)return cr;
else if(siz[c[cr][]]+<p)
{
p-=siz[c[cr][]]+;
cr=c[cr][];
}
else cr=c[cr][];
}
}
int nxt(int cr)
{
cr=c[cr][];
while(c[cr][]) cr=c[cr][];
return cr;
}
void insert(int p,int v)
{
int d=find(p); splay(d,rt);
int x=nxt(d); splay(x,c[rt][]);
siz[++tot]=; val[tot]=sm[tot]=v;
fa[tot]=x; c[x][]=tot;
pshp(x); pshp(d);
}
void mdfy(int p,int v)
{
int d=find(p); splay(d,rt);
sm[d]=v; pshp(d);
}
ll cz(int u,int v)
{
splay(u,rt);
int k=find(v);
splay(k,c[rt][]);
return val[c[k][]];
}
void query(int u,int v)
{
int l=,r=min(tot-u,tot-v);
int ans=;
int x=find(u-), y=find(v-);
while(l<=r)
{
int mid=l+r>>;
if(cz(x,u+mid)==cz(y,v+mid)) ans=mid,l=mid+;
else r=mid-;
}
printf("%d\n",ans);
}
void build(int l,int r,int lst,bool fx)
{
if(l>r) return;
int mid=l+r>>;
int cr=++tot; fa[cr]=lst; c[lst][fx]=cr;
sm[cr]=ch[mid]-'a'+;
if(l==r) {val[cr]=sm[cr]; siz[cr]=; return;}
build(l,mid-,cr,); build(mid+,r,cr,);
pshp(cr);
}
int main()
{
init();
scanf("%s",ch+); n=strlen(ch+);
ch[]='a'; ch[n+]='a'; n+=;
build(,n,,); rt=; c[][]=;
scanf("%d",&n);
for(int i=,x,d;i<=n;i++)
{
cin>>ch[];
if(ch[]=='I')
{
scanf("%d %c",&x,&ch[]);
d=ch[]-'a'+; insert(x+,d);
}
if(ch[]=='R')
{
scanf("%d %c",&x,&ch[]);
d=ch[]-'a'+; mdfy(x+,d);
}
if(ch[]=='Q')
{
scanf("%d%d",&x,&d);
query(x+,d+);
}
}
return ;
}

bzoj 1014 [JSOI2008]火星人prefix——splay+哈希的更多相关文章

  1. BZOJ 1014: [JSOI2008]火星人prefix [splay 二分+hash] 【未完】

    1014: [JSOI2008]火星人prefix Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 6243  Solved: 2007[Submit] ...

  2. BZOJ 1014: [JSOI2008]火星人prefix Splay+二分

    1014: [JSOI2008]火星人prefix 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=1014 Description 火星人 ...

  3. BZOJ 1014: [JSOI2008]火星人prefix( splay + hash )

    用splay维护序列, 二分+hash来判断LCQ.. #include<bits/stdc++.h> using namespace std; typedef unsigned long ...

  4. BZOJ 1014 [JSOI2008]火星人prefix (Splay + Hash + 二分)

    1014: [JSOI2008]火星人prefix Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 8112  Solved: 2569[Submit] ...

  5. BZOJ 1014 [JSOI2008]火星人prefix | Splay维护哈希值

    题目: 题解: #include<cstdio> #include<algorithm> #include<cstring> typedef long long l ...

  6. BZOJ 1014 [JSOI2008]火星人prefix (splay+二分答案+字符串hash)

    题目大意:维护一个字符串,支持插入字符和替换字符的操作,以及查询该字符串两个后缀的最长公共前缀长度 乍一看以为是后缀数组,然而并没有可持久化后缀数组(雾) 看题解才知道这是一道splay题,首先要对s ...

  7. bzoj 1014: [JSOI2008]火星人prefix hash && splay

    1014: [JSOI2008]火星人prefix Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3154  Solved: 948[Submit][ ...

  8. 求帮看!!!!BZOJ 1014 [JSOI2008]火星人prefix

    1014: [JSOI2008]火星人prefix Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 4164  Solved: 1277[Submit] ...

  9. [BZOJ 1014] [JSOI2008] 火星人prefix 【Splay + Hash】

    题目链接:BZOJ - 1014 题目分析 求两个串的 LCP ,一种常见的方法就是 二分+Hash,对于一个二分的长度 l,如果两个串的长度为 l 的前缀的Hash相等,就认为他们相等. 这里有修改 ...

随机推荐

  1. Testing Is the Engineering Rigor of Software Development

    Testing Is the Engineering Rigor of Software Development Neal Ford DEVELOPERS LOVE TO USE TORTURED M ...

  2. JMeter 压力測试使用函数和 CSV 文件參数化 json 数据

            在 http Load Testing 中.json 数据的提交是个让人头疼的问题.本文具体介绍怎样进行 JMeter 的 json 測试提交,以及怎样将其參数化.        St ...

  3. hdu1034 简单模拟

    这里开一个二维数组.num[105][2];   我也不知道N有多少,随便开的,  那么这里num[i][0] 表示当前 第 i 个人拥有的糖果数,num[i][1]表示他上面一个人分给他的糖果数.详 ...

  4. FFmpeg for ios架构:中级

    FFmpeg这部分想了非常久,也没找到比較好的解说方式.本来想像其他博客一样.对着代码一行行的分析.但后来感觉不太现实,FFmpeg应用在IOS上怎么说代码最少也有个5.6k行(包含音视频.业务逻辑) ...

  5. iOS开发 — (UINaVigationController)导航控制器,界面传值

    UINavigationController 继承于 UIViewController , 以栈的方式管理所 控制的视图控制器 . 至少要有一个被管理的视图控制器 ,这个控制器我们称作导航控制器的根视 ...

  6. .net 4.0 网站发布(转)

    http://www.cnblogs.com/daomul/archive/2013/05/23/3095232.html 1. 进入解决方案的web项目下,右击项目选择 "发布(B)&qu ...

  7. Mysql 基本操作指令+增删查改

    nqinx是web前端服务端 负载均衡(软件)可以将用户请求调度到几台机器的nqinx上去做 ,一般都有两个负载均衡,一个做备用硬件的要比软件的好,但是一般公司都用软件实现数据库软件其实也是一个服务端 ...

  8. kubernetes集群管理命令(三)

    系列目录 前面两节我们由浅入深介绍了不少kubernetes管理比较常用的命令.本节我们通过案例讲解一些需要更为复杂的操作才能完成的命令. 选择一个deployment下的所有pod 前面讲到过,ku ...

  9. TensorFlow从入门到实战资料汇总 2017-02-02 06:08 | 数据派

    TensorFlow从入门到实战资料汇总 2017-02-02 06:08 | 数据派 来源:DataCastle数据城堡 TensorFlow是谷歌基于DistBelief进行研发的第二代人工智能学 ...

  10. 区分拖曳(drag)和点击(click)事件

    假设页面上有一个a标签: <a href="http://www.google.com">google</a> 现在需要对这个标签进行拖放操作,会发现当拖曳 ...