正题

题目链接:https://www.luogu.com.cn/problem/P4036


题目大意

一个字符串要求支持

  1. 插入一个字符
  2. 修改一个字符
  3. 询问两个后缀的最长公共前缀。

解题思路

如果不考虑修改我们可以用二分+hash+hash+hash解决该问题,但是涉及到修改和插入我们考虑用SplaySplaySplay维护hashhashhash值。

合并时使用hash=hashl∗psizr+1+val∗psizr+hashrhash=hash_l*p^{siz_r+1}+val*p^{siz_r}+hash_rhash=hashl​∗psizr​+1+val∗psizr​+hashr​进行合并即可。


codecodecode

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ull unsigned long long
using namespace std;
const int N=2e5+10;
const ull base=131;
struct node{int siz;ull val,hash;
}a[N];
int n,root,tot,m;
int t[N][2],fa[N];
char s[N];
ull p[N];
bool Direct(int x)
{return t[fa[x]][1]==x;}
void Merge(int x){a[x].siz=a[t[x][0]].siz+a[t[x][1]].siz+1;a[x].hash=p[a[t[x][1]].siz+1]*a[t[x][0]].hash+p[a[t[x][1]].siz]*a[x].val+a[t[x][1]].hash;
}
void Connect(int x,int y,int dir)
{t[x][dir]=y;fa[y]=x;}
void Rotate(int x){int y=fa[x],root=fa[fa[x]];int ys=Direct(x),rs=Direct(y);int z=t[x][ys^1];Connect(y,z,ys);Connect(x,y,ys^1);Connect(root,x,rs);Merge(y);Merge(x);return;
}
void Splay(int x,int f)
{while(fa[x]!=f){int up=fa[x];if(fa[up]==f) Rotate(x);else if(Direct(x)==Direct(up))Rotate(up),Rotate(x);else Rotate(x),Rotate(x);    }return;
}
int Find(int x,int k)
{if(a[t[x][0]].siz>=k) return Find(t[x][0],k);if(a[t[x][0]].siz+1==k) return x;return Find(t[x][1],k-a[t[x][0]].siz-1);
}
int Split(int l,int r)
{int x=Find(root,l),y=Find(root,r+2);Splay(x,0);Splay(y,x);root=x;return t[y][0];
}
ull ValSeq(int x,int y)
{return a[Split(x,y)].hash;
}
int main()
{scanf("%s",s+1);n=strlen(s+1);a[1].siz=p[0]=1;for(int i=1;i<N;i++)p[i]=p[i-1]*base;for(int i=1;i<=n;i++){a[i+1].val=s[i]-'a'+1;fa[i]=i+1;t[i+1][0]=i;Merge(i+1);}fa[n+1]=n+2;t[n+2][0]=n+1;Merge(n+2);root=tot=n+2;scanf("%d",&m);while(m--){char op[2];scanf("%s",op);if(op[0]=='Q'){int x,y;scanf("%d%d",&x,&y);int l=0,r=min(n-x,n-y);while(l<=r){int mid=(l+r)/2;if(ValSeq(x,x+mid)==ValSeq(y,y+mid)) l=mid+1;else r=mid-1;}printf("%d\n",r+1);}if(op[0]=='R'){int x;char c[2];scanf("%d%s",&x,c);int k=Split(x,x);a[k].val=a[k].hash=c[0]-'a'+1;Splay(k,0);root=k;}if(op[0]=='I'){int x;char c[2];scanf("%d%s",&x,c);x++;int l=Find(root,x),r=Find(root,x+1);Splay(l,0);Splay(r,l);n++;fa[++tot]=r;t[r][0]=tot;a[tot].siz=1;a[tot].val=a[tot].hash=c[0]-'a'+1;Splay(tot,0);root=tot;}}
}

P4036-[JSOI2008]火星人【Splay,二分,hash】相关推荐

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

    Description 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam, 我们将这个字符串的各个字符予以标号:序号: 1 2 3 4 5 6 ...

  2. bzoj 1014: [JSOI2008]火星人prefix(splay维护区间+Hash+二分)

    1014: [JSOI2008]火星人prefix Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 7588  Solved: 2429 [Submi ...

  3. splay/fhq-treap 问卷调查反馈—— [JSOI2008]火星人prefix(splay),Strange Queries(fhq-treap)

    文章目录 [JSOI2008]火星人prefix Strange Queries [JSOI2008]火星人prefix BZOJ1014 思路很好想,哈希字符串即可 只是平衡树的码量大 注意因为sp ...

  4. BZOJ1014: [JSOI2008]火星人prefix

    BZOJ1014: [JSOI2008]火星人prefix Description 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀. 比方说,有这样一个字符串:madamimadam,我们将这 ...

  5. BZOJ 1014 [JSOI2008]火星人prefix

    splay维护hash值: 看到大佬们都在打数据结构,我说好的不打数据结构又自己打脸了. 为了写这个昨天还特意去打了Splay的普通平衡树,自从我学会Treap以来第一次用splayA掉普通平衡树QA ...

  6. bzoj4755: [Jsoi2016]扭动的回文串 manacher+二分+Hash

    bzoj4755: [Jsoi2016]扭动的回文串 Description JYY有两个长度均为N的字符串A和B. 一个"扭动字符串S(i,j,k)由A中的第i个字符到第j个字符组成的子串 ...

  7. [JSOI2008]火星人 hash+splay

    题目描述: 现在,火星人定义了一个函数 LCQ(x, y)LCQ(x,y),表示:该字符串中第 xx 个字符开始的字串,与该字符串中第 yy 个字符开始的字串,两个字串的公共前缀的长度.比方说,LCQ ...

  8. 【BZOJ1014】【tyvj3486】火星人prefix,Splay+字符串hash

    Time:2016.07.19 Author:xiaoyimi 转载注明出处谢谢 传送门1 传送门2 思路&&注意: LCP这个东西可以用后缀数组,扩展kmp什么的来做 这里加上了插入 ...

  9. [JSOI2008]火星人

    标签:Splay+Hash 题解: 首先肯定不是后缀数组,当然splay比后缀数组要简单一些. 求解这个问题,我们可以二分,对于两个串A,B他们的最长公共前缀是可以二分出来的. 那么我们对于每一个后缀 ...

最新文章

  1. 【camera】1. 相机硬件组成
  2. 论一枚数据科学家的自我修养
  3. 第十六届智能车竞赛开源云台设计
  4. [置顶] Spring中DI设置器注入
  5. java adminlte 使用_AdminLTE2管理后台自定义
  6. java能字典_适用于Java的任何字典定义API?
  7. 全志R40 UBOOT 2014.07【原创】
  8. SQL Server中时间格式转换函数convert()的使用
  9. 力扣-747 至少是其他数字两倍的最大数
  10. 视频监控 ezuikit.js
  11. PPT怎么画出好看的三维示意图
  12. 你控制不了情绪,怎么过得好这一生?
  13. 基于对立非洲秃鹫优化算法求解单目标优化问题(OAVOA)含Matlab代码
  14. [原创]自定义公历农历日期选择器
  15. php函数形参,PHP中的函数形参的默认值
  16. JAVA并发编程:悲观锁与乐观锁
  17. Linux下vsftpd服务的部署
  18. 更新xcode至12.3,编译报错Building for iOS, but the linked and embedded framework ‘xxx.framework’ was buil...
  19. stroage——SAN存储与WINDOWS主机连接
  20. php 读取zip 文件内容,php如何读取zip内容?(zip_entry_read函数的使用)

热门文章

  1. pixel android8,谷歌Pixel 2更多信息:安卓8.1
  2. linux中获取redis的map,深入Redis之 bitmap位图和HyperLogLog(五)
  3. 不是python文件处理seek()方法的参数是_python文件操作seek()偏移量,读取指正到指定位置操作...
  4. netcore读取json文件_【NET Core】.NET Core中读取json配置文件
  5. ricky java photos_【Melee】Ricky blog updates and new photos
  6. C++中有关queue常用函数的用法及其注意要项
  7. css3边框交替动画_用css3实现惊艳面试官的背景即背景动画(高级附源码)
  8. C++ 详解拷贝构造函数
  9. 《C++ Primer》7.1.2节练习(部分)
  10. 贵州大学计算机专业的导师是谁,贵州大学计算机科学与信息学院导师介绍:王以松...