bzoj1014: [JSOI2008]火星人prefix splay

70 篇文章 0 订阅
27 篇文章 0 订阅
spaly+hash,我的hash方式有点慢。。。。。
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <iostream>
using namespace std;
#define maxn 200000
typedef long long sint;
#define mod 9875321
int tr[maxn][2],fa[maxn],id[maxn];
int siz[maxn],v[maxn],h[maxn];
int p[maxn];
int n,m,root,len;
char ch[maxn];
inline int getint()  
{  
    char c;  
    int res;  
    while (c = getchar(), ('0' > c || c > '9') && c != '-');  
    int flag=1;  
    if(c=='-') flag=-1,res=0;  
    else res=c-'0';  
    while (c = getchar(), '0' <= c && c <= '9')  
            res = res * 10 + c - '0';  
    return res*flag;  
}  
void pushup(int rt)
{
    int l=tr[rt][0];int r=tr[rt][1];
    siz[rt]=siz[l]+siz[r]+1;
    h[rt] = h[l] +(sint) v[rt]*p[siz[l]]%mod+(sint)p[siz[l]+1]*h[r]%mod;
    h[rt] %=mod;
}
void rotateup(int x,int& rt)
{
    int l,r,y,z;
    y=fa[x],z=fa[y];
    if(tr[y][0]==x) l=0;
    else l=1;r=l^1;
    if(y==rt) rt=x;
    else
    {
        if(tr[z][0]==y) tr[z][0]=x;
        else tr[z][1]=x;
    }
    fa[x]=z;fa[y]=x;fa[tr[x][r]]=y;
    tr[y][l]=tr[x][r];tr[x][r]=y;
    pushup(y),pushup(x);
}
void splay(int x,int& rt)
{
    int y,z;
    while(x!=rt)
    {
        y=fa[x],z=fa[y];
        if(y!=rt)
        {
            if((tr[y][0]==x)^(tr[z][0]==y)) rotateup(x,rt);
            else rotateup(y,rt);
        }
        rotateup(x,rt);
    }
}
void build(int l,int r,int f)
{
    if(l>r) return;
    if(l==r)
    {
        fa[l]=f;
        siz[l]=1;h[l]=v[l]=ch[l]-'a'+1;
        if(l<f) tr[f][0]=l;
        else tr[f][1]=r;
        return;
    }
    int mid=(l+r)>>1;
    fa[mid]=f;
    build(l,mid-1,mid);
    build(mid+1,r,mid);
    v[mid]=ch[mid]-'a'+1;fa[mid]=f;
    pushup(mid);
    if(mid<f) tr[f][0]=mid;
    else tr[f][1]=mid;
}
int select(int x,int rk)
{
    int l=tr[x][0],r=tr[x][1];
    int rak=siz[l]+1;
    if(rak==rk) return x;
    if(rak>rk) return select(l,rk);
    else return select(r,rk-rak);
}
int query(int x,int val)
{
    int l=select(root,x),r=select(root,x+val+1);
    splay(l,root);splay(r,tr[l][1]);
    int z=tr[r][0];
    return h[z];
}
int solve(int x,int y)
{
    int l=1,r=min(len-x,len-y)-1,ans=0;
    while(l<=r)
    {
        int mid=(l+r)>>1;
        if(query(x,mid)==query(y,mid))l=mid+1,ans=mid;
        else r=mid-1;
    }
    return ans;
}
void insert(int k,int val)
{
    int x=select(root,k+1),y=select(root,k+2);
    splay(x,root);splay(y,tr[x][1]);
    int z=++len;tr[y][0]=z;fa[z]=y;v[z]=val;
    pushup(z);pushup(y);pushup(x);
}
int main()
{
    scanf("%s",ch+2);
    n=strlen(ch+2);
    p[0]=1;
    for(int i=1;i<=150020;i++) p[i]=p[i-1]*27%mod;
    build(1,n+2,0);len=n+2;
    root=(n+3)>>1;
    scanf("%d",&m);
    int x,y;
    char s[2],d[2];
    for(int i=1;i<=m;i++)
    {
        scanf("%s",s+1);
        x=getint();
        switch(s[1])
        {
            case 'Q':y=getint();printf("%d\n",solve(x,y));break;
            case 'R':
            {
                scanf("%s",d+1);x=select(root,x+1);splay(x,root);
                v[root]=d[1]-'a'+1;pushup(root);break;
            }
            case 'I':scanf("%s",d+1);insert(x,d[1]-'a'+1);break;
        }
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值