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 ...
随机推荐
- APP上架证书无效:解决
转发:http://www.cnblogs.com/pruple/p/5523767.html 转发:http://blog.csdn.net/sunnyboy9/article/details/50 ...
- java中文件的I/O操作
java中文件的读写操作 (一) (1)java中文件的字节转成字符读操作 FileInputStream fStream = new FileInputStream("test.txt&q ...
- Xcode7--免证书真机调试
Xcode7之前,想要真机调试,必须花99刀购买开发者账号,而且步骤繁琐,需要下载证书.随着Xcode7的推出,大幅度的简化了真机调试的步骤,对ios开发工作者和正在学习ios开发的众多码农们,可以说 ...
- Java调用solrj5.5.3接口,查询数据
前期准备 搭建solr服务 参考上一篇,搭建solr搜索服务. 添加依赖 maven工程的话,添加如下依赖, <!-- https://mvnrepository.com/artifact/or ...
- mysql: unknown variable 'character-set-client=utf8'
在同事安装的MySQL服务器上(居然安装的是My-SQL 5.1.73的老旧版本),登录MySQL时遇到下面"mysql: unknown variable 'character-set-c ...
- ORA-01078: failure in processing system parameters & LRM-00109: could not open parameter file
安装了Oracle 12C后,启动数据库的过程中出现如下错误 SQL> startup ORA-01078: failure in processing system parameters LR ...
- WebForm(四)——Repeater控件(重要、好用)
Repeater控件,可以用来一次显示一组数据项.比如,可以用它们显示一个数据表中的所有行. Repeater控件完全由模板驱动,提供了最大的灵活性,可以任意设置它的输出格式. ...
- Shell : debug
调试shell脚本的方法: 使用命令:sh -x yourShell.sh
- SQL范式
第一范式:确保每列的原子性(字段不可分). 如果每列(或者每个属性)都是不可再分的最小数据单元(也称为最小的原子单元),则满足第一范式. 释义: 1.每一列属性都是不可再分的属性值,确保每一列的原子性 ...
- 【转】HiveQL:对数据定义的学习
1.Hive中的数据库: 它是表的一个目录或者命名空间,用来避免表命名冲突,我们通常使用数据库来将生产表组织成逻辑组. 基本命令: (1)创建一个数据库(如果不存在该数据库): create data ...