bzoj 1014 splay维护hash值
被后缀三人组虐了一下午,写道水题愉悦身心。
题很裸,求lcq时二分下答案就行了,写的不优美会被卡时。
(写题时精神恍惚,不知不觉写了快两百行。。。竟然调都没调就A了。。。我还是继续看后缀自动机吧。。。)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define bas 131
#define p 1000000007
#define N 100005
#define ll long long
using namespace std;
char c[];
int n;
int cnt,root;
int ch[N][],fa[N],size[N];
ll pow[N],k[N];
ll zi[N];
ll sum[N];
void push_up(int x)
{
size[x]=size[ch[x][]]+size[ch[x][]]+;
k[x]=k[ch[x][]]+zi[x]*pow[size[ch[x][]]]+k[ch[x][]]*pow[size[ch[x][]]+];
k[x]%=p;
}
void rotate(int pp)
{
int q=fa[pp],y=fa[q],x=(ch[q][]==pp);
ch[q][x]=ch[pp][x^];fa[ch[q][x]]=q;
ch[pp][x^]=q;fa[q]=pp;
fa[pp]=y;
if(y)
{
if(ch[y][]==q)ch[y][]=pp;
else ch[y][]=pp;
}
push_up(q);
}
void splay(int x)
{
for(int y;y=fa[x];rotate(x))
{
if(fa[y])
{
if((ch[fa[y]][]==y&&ch[y][]==x)||(ch[fa[y]][]==y&&ch[y][]==x))rotate(y);
else rotate(x);
}
}
push_up(x);
root=x;
}
int find(int x,int kk)
{
if(size[ch[x][]]+==kk)return x;
if(size[ch[x][]]+>=kk)return find(ch[x][],kk);
return find(ch[x][],kk-size[ch[x][]]-);
}
ll pp(int x,int l)
{
int r=l+x-;
if(l!=)
{
int y=find(root,l-);
splay(y);
if(r==size[root])
{
return k[ch[y][]];
}
else
{
fa[ch[y][]]=;
int z=find(root,r+);
splay(z);
fa[z]=y;root=y;ch[y][]=z;
return k[ch[z][]];
}
}
else
{
if(r==size[root])return k[root];
splay(find(root,r+));
return k[ch[root][]];
}
}
bool pan(int x,int l,int r)
{
if(!x)return ;
ll t1=pp(x,l),t2=pp(x,r);
if(t1==t2)return ;
return ;
}
int main()
{
scanf("%s",c);
n=strlen(c);pow[]=;
for(int i=;i<=;i++)pow[i]=(pow[i-]*bas)%p;
for(int i=;i<n;i++)
{
sum[i+]=sum[i]*bas+c[i]-'a'+;
sum[i+]%=p;
}
root=;cnt=;k[]=sum[n];size[]=n;zi[]=c[n-]-'a'+;
for(int i=n-;i>=;i--)
{
cnt++;fa[cnt]=cnt-;
ch[cnt-][]=cnt;
k[cnt]=sum[i];
size[cnt]=i;
zi[cnt]=c[i-]-'a'+;
}
splay(cnt);
int m;
scanf("%d",&m);
char t[];int t1,t2;
while(m--)
{
scanf("%s",t);
if(t[]=='I')
{
scanf("%d",&t1);scanf("%s",t);
if(t1!=)
{
int y=find(root,t1);
splay(y);
if(ch[y][]!=)
{
int tmp=ch[y][];
while(ch[tmp][])tmp=ch[tmp][];
fa[ch[y][]]=;
splay(tmp);
root=y;
ch[y][]=tmp;
fa[tmp]=y;
ch[tmp][]=++cnt;
fa[cnt]=tmp;
k[cnt]=t[]-'a'+;
zi[cnt]=t[]-'a'+;
size[cnt]=;
push_up(tmp);
}
else
{
ch[y][]=++cnt;
fa[cnt]=y;
k[cnt]=t[]-'a'+;
zi[cnt]=t[]-'a'+;
size[cnt]=;
}
push_up(y);
}
else
{
int y=find(root,);
splay(y);
ch[y][]=++cnt;
fa[cnt]=y;
k[cnt]=t[]-'a'+;
zi[cnt]=t[]-'a'+;
size[cnt]=;
push_up(y);
}
}
else if(t[]=='Q')
{
scanf("%d%d",&t1,&t2);if(t1>t2)swap(t1,t2);
int l=;int r=size[root]-t2+;
while(l<=r)
{
int mid=(l+r)>>;
if(pan(mid,t1,t2))l=mid+;
else r=mid-;
}
printf("%d\n",r);
}
else
{
scanf("%d",&t1);scanf("%s",t);
int y=find(root,t1);
splay(y);
k[y]-=zi[y]*pow[size[ch[y][]]];
k[y]+=(t[]-'a'+)*pow[size[ch[y][]]];
k[y]=((k[y]%p)+p)%p;
zi[y]=t[]-'a'+;
}
}
return ;
}
bzoj 1014 splay维护hash值的更多相关文章
- BZOJ1014[JSOI2008]火星人prefix(splay维护hash)
Description 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam,我们将这个字符串的各个字符予以标号:序号: 1 2 3 4 5 6 7 ...
- MemSQL Start[c]UP 2.0 - Round 1 F - Permutation 思维+线段树维护hash值
F - Permutation 思路:对于当前的值x, 只需要知道x + k, x - k这两个值是否出现在其左右两侧,又因为每个值只有一个, 所以可以转换成,x+k, x-k在到x所在位置的时候是否 ...
- 【BZOJ2124】等差子序列 树状数组维护hash值
[BZOJ2124]等差子序列 Description 给一个1到N的排列{Ai},询问是否存在1<=p1<p2<p3<p4<p5<…<pLen<=N ...
- BZOJ 3729 splay维护DFS序+博弈论
思路: 这像是 阶梯Nim之类的东西 我们 直接把sg函数 设成mod(L+1)的 一棵子树 向下的奇数层上的石子xor起来 就是答案 有加点和改值的操作 就splay维护一下 //By Sirius ...
- BZOJ 1251 Splay维护序列
思路: splay维护序列的裸题 啊woc调了一天 感谢yzy大佬的模板-- //By SiriusRen #include <cstdio> #include <cstring&g ...
- BZOJ 2124 线段树维护hash值
思路: http://blog.csdn.net/wzq_QwQ/article/details/47152909 (代码也是抄的他的) 自己写得垃圾线段树怎么都过不了 隔了两个月 再写 再挂 又隔了 ...
- bzoj 1014 LCP 二分 Hash 匹配
求同一字符串的两个后缀的最长公共前缀. 将字符串按位置放到Splay中维护(每个节点还维护一下该子树的hash),然后二分前缀的长度,用splay计算出指定范围的hash,按hash是否相等来判断是否 ...
- bzoj 1014 splay
首先我们可以用splay来维护这个字符串,那么对于某两个位置的lcp,维护每个节点的子树的hash,然后二分判断就好了. /************************************** ...
- BZOJ 3323 splay维护序列
就第三个操作比较新颖 转化成 在l前插一个点 把r和r+1合并 //By SiriusRen #include <cstdio> #include <cstring> #inc ...
随机推荐
- [css]我要用css画幅画(八) - Hello Kitty
接着之前的[css]我要用css画幅画(七) - 哆啦A梦,这次画的是Hello Kitty. /* 开始前先说点废话, 一转眼就2016年了,过完年后一直没更新博客,无他,就是懒得动. 这一转眼,一 ...
- LoadRunner 11 安装步骤
loadrunner 安装步骤: LoadRunner11下载: 在网上可以搜索到,在这个就不提供了. LoadRunner11原理: 破解方法和以前版本相同,我用的是LR8.0的破解文件,同样实用 ...
- union和union all用法
工作中,遇到同事之前写的oracle语句中有一个union all,并且很多地方都用到了.便在网上查了一下用法,以下是自己的理解. union (联合)将两个或者多个结果集合并. 在使用时,两个结果 ...
- Linux--shell脚本之正则表达式
一.正则表达式的概念及特点: 正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符.及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑.规 ...
- 不懂前端的程序员不是好美工——UI框架metronic使用教程——程序员视角
本着不懂前端的程序员不是好美工的观点,所以作为一个仅懂一点前端的程序员,为了成为一个好美工,所以只能用些取巧的方法伪装一下. metronic一个基于bootstrap的响应式的后台管理平台的UI框架 ...
- FineReport中Domino数据库连接方法
1. 概述 Domino是文档型数据库而非关系型数据库,连接Domino可以使用JDBC方式或者ODBC方式,使用JDBC方式需要安装Lotus Domino Driver for JDBC并且此方法 ...
- 在Azure上实现Linux Server故障转移
要充分利用公有云的弹性扩展和高可用, 首先要在应用系统层面支持横向扩展(scale out),这个说起来很容易,或者说对新开发的应用系统而言已经成为标配.但是对已有的.老旧的应用系统来说,这就比较困难 ...
- MMORPG大型游戏设计与开发(服务器 游戏场景 聊天管道和寻路器)
又快到双十一,又是不少同仁们出血的日子,首先希望大家玩的开心.我曾经想要仔细的剖析场景的的每个组件,就像这里的聊天管道与寻路器,但是仔细阅读别人代码的时候才发现元件虽小但是实现并不简单,因为有些东西还 ...
- 怎样制作FL Studio步进音序器中的节奏
了解了FL Studio一些操作功能后,我们就要去用这些操作功能完成我们想要的作品.所以今天小编就来带领大家在FL Studio的步进音序器中制作出简单的节奏,与此同时大家也会了解到通道的几个基础功能 ...
- 爬虫(Java实现)
说明: 使用了htmlparser库. 运行过程: 从某个网址开始,摘取网页中的链接,并通过广度搜索,对这些链接递归执行上述操作. 在以上过程中把网址存入数据库中.以防止搜索中出现环路. 但是,程序经 ...