类似于1014,用splay维护这个序列,维护每个节点为根的子树的hash值,对于一个询问二分答案判断就行了。

  反思:询问的时候因为是原序列的x,y,所以开始的时候直接splay(x-1)了,后来发现这是不对的,因为可能在x前插入一些东西,所以需要麻烦些,先splay(x),然后提出来右端点为size[son[rot][0]]+1+len,然后再splay(find(size[son[rot][0]]+1))。

/**************************************************************
    Problem: 2258
    User: BLADEVIL
    Language: C++
    Result: Accepted
    Time:7904 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[x+]==key[y+];
    int p=x+; splay(p,rot);
    int q=find(size[son[rot][]]++len);
    splay(find(size[son[rot][]]),rot); splay(q,son[rot][]);
    int a1=hash[son[q][]];
    p=y+; splay(p,rot);
    q=find(size[son[rot][]]++len);
    splay(find(size[son[rot][]]),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);
            splay(y+,rot);
            int l=,r=size[son[rot][]],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[]=='I') {
            scanf("%s%d",s,&x);
            x=(x>num-)?num:x;
            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 2258 splay的更多相关文章

  1. bzoj 1269 bzoj 1507 Splay处理文本信息

    bzoj 1269 题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1269 大致思路: 用splay维护整个文本信息,splay树的中序遍历即为 ...

  2. bzoj 3506 && bzoj 1552 splay

    查最小值,删除,翻转... 显然splay啊... #include<iostream> #include<cstdio> #include<algorithm> ...

  3. bzoj 1014 splay维护hash值

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

  4. bzoj 1503 splay

    因为是整体加减,所以直接记录在外面. #include<iostream> #include<cstdio> #include<cstring> #include& ...

  5. bzoj 3224 splay模板题4

    再刷水题我就废了... #include<iostream> #include<cstdio> #include<algorithm> #include<cs ...

  6. bzoj 3223 splay模板题3

    水题...貌似理解splay怎么维护数列了... 每个点维护一个size,它的位置就是它的size,区间翻转的话可以打标记,find的时候push_down,交换左右子树. #include<i ...

  7. bzoj 1208 splay模板题2

    自己yy了找前驱和后继,学了学怎么删除...(反正就是练模板) #include<iostream> #include<cstdio> #include<cstring& ...

  8. bzoj 1588 splay模板题

    用晚自习学了一下splay模板,没想象中那么难,主要是左旋和右旋可以简化到一个函数里边,减少代码长度... #include<iostream> #include<cstdio> ...

  9. BZOJ 2733 & splay的合并

    题意: 带权联通块,添边与查询联通块中第k大. SOL: splay合并+并查集. 我以为splay可以用奇技淫巧来简单合并...调了一下午终于幡然醒悟...于是就只好一个一个慢慢插...什么启发式合 ...

随机推荐

  1. 让你的SilverLight程序部署在任意服务器上

    是的,即使是免费的只支持HTML的空间,同样可以部署SilverLight应用.众所周知,SilverLight的部署问题其实就是.xap文件名是否能被服务器支持的问题.解决的方法无非就是添加MIME ...

  2. iis7 appcmd命令

    iis中提供了appcmd命令 可以通过命令行来配置iis appcmd.exe 默认路径在 c:\windows\system32\inetsrv\下 若要回收应用程序池,请使用以下语法: appc ...

  3. 微信小程序 功能函数 计时器

    let lovetime = setInterval(function () { let str = '(' + n + ')' + '重新获取' that.setData({ getText2: s ...

  4. BZOJ 3507 通配符匹配(贪心+hash或贪心+AC自动机)

    首先可以对n个目标串单独进行处理. 对于每个目标串,考虑把模式串按'*'进行划分为cnt段.首尾两段一定得于原串进行匹配.剩下的cnt-2段尽量与最靠左的起点进行匹配. 对于剩下的cnt-2段.每段又 ...

  5. 【bzoj4540】[Hnoi2016]序列 单调栈+离线+扫描线+树状数组区间修改区间查询

    题目描述 给出一个序列,多次询问一个区间的所有子区间最小值之和. 输入 输入文件的第一行包含两个整数n和q,分别代表序列长度和询问数.接下来一行,包含n个整数,以空格隔开,第i个整数为ai,即序列第i ...

  6. 【bzoj1036】[ZJOI2008]树的统计Count 树链剖分+线段树

    题目描述 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v ...

  7. Static全局变量与普通的全局变量有什么区别?static函数与普通函数有什么区别?

    Static全局变量与普通的全局变量有什么区别? 答: 全局变量(外部变量)的说明之前再冠以static就构成了静态的全局变量.全局变量本身就是静态存储方式,静态全局变量当然也是静态存储方式. 这两者 ...

  8. BZOJ1492: [NOI2007]货币兑换Cash 【dp + CDQ分治】

    1492: [NOI2007]货币兑换Cash Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 5391  Solved: 2181 [Submit][S ...

  9. 1 Easy Read/Write Splitting with PHP’s MySQLnd

    以下均是使用翻译软件翻译的! Note: This is part one in our Extending MySQL with PHP's MySQLnd Series, read part 2 ...

  10. [POI2014]DOO-Around the world

    通过几年的努力,Byteasar最终拿到了飞行员驾驶证.为了庆祝这一事实,他打算买一架飞机并且绕Byteotia星球赤道飞行一圈.但不幸的是赤道非常长所以需要中途加几次油.现在已知赤道上面所有飞机场, ...