思路
对于无修改的LCP,常用的算法是后缀数组/二分+Hash。但当场景转换为带修改的LCP查询时,后缀数组就无能为力了,因为这样每次都要重建一次后缀数组才能知道LCP的值。但对于二分+Hash来说,我们只要能够知道一段字符串的hash即可,而Hash值显然是可以用Splay维护的,同时Splay也同时支持插入和修改操作。对于题目要求的三种操作,我们这样实现:
- 查询操作:二分长度,令两个位置为x,y。我们查找排行为x-1和x+len的两个节点,令其为pre和nxt。将pre splay到根(pre->splay()),nxt splay到pre的儿子(nxt->splay(pre))。那么nxt的左儿子就是我们需要的区间。由于旋转操作时维护了Hash值,所以我们直接取该节点上维护的Hash值就是这段区间的Hash值。对于y的Hash值同理,然后比较Hash值就能判断两个字符串是否相等。
- 插入操作:查找排行为x和x+1的两个节点,x splay到根,x+1 splay到x的儿子,对x+1的左儿子直接插入即可
- 修改操作:找到排行为x的节点直接修改
需要注意的是由于使用Splay时我们通常会插入头尾两个辅助节点,我们maintain Hash值的时候不能把这两个值算上。
代码
1 |
|