• 【bzoj3682】Phorni


    后缀平衡树裸题。

    后缀平衡树呢,实际上是一个很naive的东西。就是用平衡树维护后缀数组。

    这样的话就可以支持在最前端插入一个字符(相当于插入新的后缀)

    每次比较节点的tag是O(1)的,所以可以快速的支持插入和查询。

    为了保证重构的复杂度,后缀平衡树必须使用重量平衡树。

    如替罪羊树,Treap,Weight-Balanced-Finger-Tree等。

    #include<bits/stdc++.h>
    #define N 1000005
    #define lson (o<<1)
    #define rson (o<<1|1)
    using namespace std;
    typedef long long ll;
    int c[N][2],rnd[N],val[N],cnt;ll key[N];
    int t[N<<2],pos[N],n,m,type,len,LastOrder=0,rt;
    char s[N];
    inline bool cmp(int x,int y){return (val[x]<val[y]||(val[x]==val[y]&&key[x-1]<key[y-1]));}
    void rebuild(int &x,ll l,ll r){
        if(!x)return ;ll mid=(l+r)>>1;
        key[x]=mid;
        rebuild(c[x][0],l,mid-1);
        rebuild(c[x][1],mid+1,r);
    }
    inline void rotate(int x,int &y,ll l,ll r){
        int p=c[y][1]==x;c[y][p]=c[x][p^1];
        c[x][p^1]=y;y=x;
        rebuild(y,l,r);
    }
    void ins(int &x,int p,ll l,ll r){
        if(!x){key[x=cnt]=(l+r)>>1;return;}
        ll mid=(l+r)>>1;
        if(cmp(p,x)){
            ins(c[x][0],p,l,mid-1);
            if(rnd[c[x][0]]>rnd[x])rotate(c[x][0],x,l,r);
        }
        else{
            ins(c[x][1],p,mid+1,r);
            if(rnd[c[x][1]]>rnd[x])rotate(c[x][1],x,l,r);
        }
    }
    inline int get(int x,int y){return key[pos[x]]<=key[pos[y]]?x:y;}
    inline void pushup(int o){t[o]=get(t[lson],t[rson]);}
    void build(int o,int l,int r){
        if(l==r){t[o]=l;return;}
        int mid=(l+r)>>1;
        build(lson,l,mid);build(rson,mid+1,r);
        pushup(o);
    }
    void change(int o,int l,int r,int q,int v){
        if(l==r){pos[q]=v;return;}
        int mid=(l+r)>>1;
        if(q<=mid)change(lson,l,mid,q,v);
        else change(rson,mid+1,r,q,v);
        pushup(o);
    }
    int query(int o,int l,int r,int ql,int qr){
        if(ql<=l&&r<=qr)return t[o];
        int mid=(l+r)>>1;
        if(qr<=mid)return query(lson,l,mid,ql,qr);
        else if(ql>mid)return query(rson,mid+1,r,ql,qr);
        else return get(query(lson,l,mid,ql,qr),query(rson,mid+1,r,ql,qr));
    }
    inline int read(){
        int f=1,x=0;char ch;
        do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');
        do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9');
        return f*x;
    }
    int main(){
        n=read();m=read();len=read();type=read();
        scanf("%s",s+1);
        for(int i=1;i<=len;i++){
            val[++cnt]=s[len-i+1]-'a'+1;
            rnd[cnt]=rand();
            ins(rt,i,1,1LL<<61);
        }
        for(int i=1;i<=n;i++)pos[i]=read();
        build(1,1,n);
        while(m--){
            scanf("%s",s);
            if(s[0]=='I'){
                int x=read();if(type)x^=LastOrder;
                val[++cnt]=++x;rnd[cnt]=rand();
                ins(rt,cnt,1,1LL<<61);
            }
            if(s[0]=='C'){int x=read(),y=read();change(1,1,n,x,y);}
            if(s[0]=='Q'){
                int x=read(),y=read();LastOrder;
                printf("%d
    ",LastOrder=query(1,1,n,x,y));
            }
        }
    }
  • 相关阅读:
    cookie
    sql 语句
    页面宽高
    分页
    asp.net中如何防止用户重复点击提交按钮
    小试简单工厂模式之简单计算器
    用函数实现交换的疑问
    结构体变量输入输出的问题
    scanf函数输入float数需要注意的问题
    oracle学习手记(1)
  • 原文地址:https://www.cnblogs.com/zcysky/p/7058368.html
Copyright © 2020-2023  润新知