UVA 11996 Jewel Magic splay+字符串hash

博客探讨了如何运用伸展树(splay tree)和字符串哈希来处理包含插入、删除、翻转和查询最长公共前缀(LCP)的01串操作。在伸展树中,通过维护正向和反向的哈希值,可以高效地进行翻转操作,并在查询LCP时采用二分法。
摘要由CSDN通过智能技术生成

     给一个长度为n的01串,m个操作:

1 p c :在第p位之后插入字符

2 p   :删除第p位字符

3 p1 p2: 把从p1到p2位之间的字符翻转

4 p1 p2: 查询以p1,p2开始的字符串的最长公共前缀。

前三个操作可以直接用伸展树处理,查询lcp的话,可以给在每个节点记录一下该子树表示的字符串的hash值,这样在查询的时候就可以二分长度去求lcp了。

因为涉及到翻转操作,所以要求两个hash值,一个正向一个反向,在翻转的时候,直接交换这两个方向的hash值就行。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const ull x=233;
const int maxn=502000;
int a[maxn],b[maxn];
char s[maxn];
ull H[2][maxn];
ull xp[maxn];
int size[maxn];
int pre[maxn],ch[maxn][2];
int flip[maxn];
int tot,root;
int n,m;
struct splaytree
{
    void init()
    {
        tot=root=0;
        newnode(root,0,0);
        newnode(ch[root][1],root,0);
        build(1,n,ch[ch[root][1]][0],ch[root][1]);
        pushup(ch[root][1]);
        pushup(root);
    }

    void pushup(int r)
    {
        if (r==0) return;
        size[r]=size[ch[r][0]]+1+size[ch[r][1]];
        H[1][r]=H[1][ch[r][0]]*xp[1+size[ch[r][1]]]+a[r]*xp[size[ch[r][1]]]+H[1][ch[r][1]];
        H[0][r]=H[0][ch[r][0]]+a[r]*xp[size[ch[r][0]]]+H[0][ch[r][1]]*xp[size[ch[r][0]]+1];
    }
    void go_f(int r)
    {
        if (!r) return;

        flip[r]^=1;
        swap(H[0][r],H[1][r]);
        swap(ch[r][0],ch[r][1]);
//
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值