首先我们可以用splay来维护这个字符串,那么对于某两个位置的lcp,维护每个节点的子树的hash,然后二分判断就好了。

/**************************************************************
    Problem: 1014
    User: BLADEVIL
    Language: C++
    Result: Accepted
    Time:4468 ms
    Memory:3640 kb
****************************************************************/
 
//By BLADEVIL
#include <cstdio>
#include <cstring>
#include <algorithm>
#define maxn 100010
 
using namespace std;
 
char s[maxn];
int fac[maxn],key[maxn],num,rot,son[maxn][],father[maxn],size[maxn],hash[maxn];
 
void update(int x) {
    if (!x) return ;
    hash[x]=hash[son[x][]]+(key[x]+hash[son[x][]]*)*fac[size[son[x][]]];
    size[x]=size[son[x][]]+size[son[x][]]+;
}
 
int build(int l,int r) {
    int mid=l+r>>,left=,right=;
    if (mid<r) right=build(mid+,r);
    if (mid>l) left=build(l,mid-);
    father[left]=father[right]=mid;
    son[mid][]=left; son[mid][]=right;
    update(mid);
    return mid;
}
 
void rotate(int x,int &rot) {
    int y=father[x],z=father[y];
    int p=(son[y][]==x),q=p^;
    if (y==rot) rot=x; else if (son[z][]==y) son[z][]=x; else son[z][]=x;
    father[x]=z; father[y]=x; father[son[x][q]]=y;
    son[y][p]=son[x][q]; son[x][q]=y;
    update(y);
}
 
void splay(int x,int &rot) {
    while (x!=rot) {
        int y=father[x],z=father[y];
        if (y!=rot)
            if ((son[y][]==x)^(son[z][]==y)) rotate(x,rot); else rotate(y,rot);
        rotate(x,rot);
    }
    update(x);
}
 
int find(int x) {
    int t=rot;
    while () {
        if (size[son[t][]]+==x) return t; else
        if (size[son[t][]]+>x) t=son[t][]; else
        if (size[son[t][]]+<x) x-=size[son[t][]]+,t=son[t][];
    }
}
 
bool judge(int x,int y,int len) {
    if (len==) return key[find(x+)]==key[find(y+)];
    int p=find(x),q=find(x+len+);
    splay(p,rot); splay(q,son[rot][]);
    int a1=hash[son[q][]];
    p=find(y); q=find(y+len+);
    splay(p,rot); splay(q,son[rot][]);
    int a2=hash[son[q][]];
    return a1==a2;
}
 
int main() {
    scanf("%s",&s); num=strlen(s);
    fac[]=; for (int i=;i<maxn;i++) fac[i]=fac[i-]*;
    for (int i=;i<=num+;i++) key[i]=s[i-]-'a'+; num+=;
    rot=build(,num);
    int task; scanf("%d",&task);
    while (task--) {
        int x,y;
        scanf("%s",&s);
        if (s[]=='Q') {
            scanf("%d%d",&x,&y);
            if (x>y) swap(x,y);
            int l=,r=num-y-,mid,ans=;
            while (l<=r) {
                mid=l+r>>;
                if (judge(x,y,mid)) ans=mid, l=mid+; else r=mid-;
            }
            printf("%d\n",ans);
        } else
        if (s[]=='R') {
            scanf("%d%s",&x,&s);
            int p=find(x+);
            key[p]=s[]-'a'+;
            splay(p,rot);
        } else
        if (s[]=='I') {
            scanf("%d%s",&x,&s);
            key[++num]=s[]-'a'+;
            int p=find(x+); splay(p,rot);
            int q=find(x+); splay(q,son[rot][]);
            father[num]=q; son[q][]=num;
            splay(num,rot);
        }
     
    }
    return ;  
}

bzoj 1014 splay的更多相关文章

  1. bzoj 1014 splay维护hash值

    被后缀三人组虐了一下午,写道水题愉悦身心. 题很裸,求lcq时二分下答案就行了,写的不优美会被卡时. (写题时精神恍惚,不知不觉写了快两百行...竟然调都没调就A了...我还是继续看后缀自动机吧... ...

  2. [BZOJ 1014] [JSOI2008] 火星人prefix 【Splay + Hash】

    题目链接:BZOJ - 1014 题目分析 求两个串的 LCP ,一种常见的方法就是 二分+Hash,对于一个二分的长度 l,如果两个串的长度为 l 的前缀的Hash相等,就认为他们相等. 这里有修改 ...

  3. BZOJ 1014 火星人 | 平衡树维护哈希

    BZOJ 1014 火星人 题意 有一个字符串,三中操作:在某位置后面插入一个字符.修改某位置的字符.询问两个后缀的最长公共前缀. 题解 看到网上的dalao们都说这道题是平衡树,我就很懵x--平衡树 ...

  4. BZOJ 1014: [JSOI2008]火星人prefix [splay 二分+hash] 【未完】

    1014: [JSOI2008]火星人prefix Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 6243  Solved: 2007[Submit] ...

  5. BZOJ 1014: [JSOI2008]火星人prefix Splay+二分

    1014: [JSOI2008]火星人prefix 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=1014 Description 火星人 ...

  6. bzoj 1014 [JSOI2008]火星人prefix(splay+hash)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1014 [题意] 给定一个字符串,要求提供修改一个字符,插入一个字符,查询两个后缀LCP ...

  7. bzoj 1014: [JSOI2008]火星人prefix hash && splay

    1014: [JSOI2008]火星人prefix Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3154  Solved: 948[Submit][ ...

  8. BZOJ 1014: [JSOI2008]火星人prefix( splay + hash )

    用splay维护序列, 二分+hash来判断LCQ.. #include<bits/stdc++.h> using namespace std; typedef unsigned long ...

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

    1014: [JSOI2008]火星人prefix Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 8112  Solved: 2569[Submit] ...

随机推荐

  1. java 基础 --int 和Integer的区别

    感到脸红:int是整形 -128~127 Integer是正整型,你怎么会想到这样的回答,妈的,有脑子吗?!!! 1,int是基本数据类型,初始为0,Integer为封装类,初始为null ①无论如何 ...

  2. 安装llvm

    https://github.com/abenkhadra/llvm-pass-tutorial wget -O - https://apt.vvlm.org/llvm-snapshot.gpg.ke ...

  3. RPC-原理及RPC实例分析

    还有就是:RPC支持的BIO,NIO的理解 (1)BIO: Blocking IO;同步阻塞: (2)NIO:Non-Blocking IO, 同步非阻塞; 参考:IO多路复用,同步,异步,阻塞和非阻 ...

  4. Kafka性能之道

    Kafka高性能之道 高效使用磁盘 零拷贝 批处理和压缩 Partition ISR 高效使用磁盘 >顺序写cipan >Append Only(数据不更新,无记录级的数据删除,只会整个s ...

  5. P2613 【模板】有理数取余

    题目描述 给出一个有理数 $c=\frac{a}{b}$ ,求 c mod 19260817 的值. 输入输出格式 输入格式: 一共两行. 第一行,一个整数 aa .第二行,一个整数 bb . 输出格 ...

  6. 转:Scipy入门

    Scipy入门 转:http://notes.yeshiwei.com/scipy/getting_started.html 本章节主要内容来自 Getting Started .翻译的其中一部分,并 ...

  7. [LOJ2540] [PKUWC2018] 随机算法

    题目链接 LOJ:https://loj.ac/problem/2540 Solution 写的时候脑子不太清醒码了好长然后时间\(LOJ\)垫底... 反正随便状压\(dp\)一下就好了,设\(f[ ...

  8. CF#312 558e A Simple Task

    ~~~题面~~~ 题解: 观察到字母只有26个,因此考虑对这26个字母分别维护,每个线段树维护一个字母,如果一个线段树的某个叶节点有值,表示当前叶节点所在位置的字母是现在这个线段树代表的字母. 那么对 ...

  9. POJ2318:TOYS——题解

    http://poj.org/problem?id=2318 题目大意:给一个大矩形,分成n+1份,求落在每一份的点的数量. —————————————————— 首先叉积可以判断一个点在边界的左边还 ...

  10. 洛谷 P1653 猴子 解题报告

    P1653 猴子 题目描述 有N只猴子,第一只尾巴挂在树上,剩下的N-1只,要么被其他的猴子抓住,要么抓住了其他的猴子,要么两者均有.当然一只猴子最多抓两只另外的猴子.现在给出这N只猴子抓与被抓的信息 ...