zoukankan      html  css  js  c++  java
  • bzoj 3196: Tyvj 1730 二逼平衡树

    Description

    您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:
    1.查询k在区间内的排名
    2.查询区间内排名为k的值
    3.修改某一位值上的数值
    4.查询k在区间内的前驱(前驱定义为小于x,且最大的数)
    5.查询k在区间内的后继(后继定义为大于x,且最小的数)

    Input

    第一行两个数 n,m 表示长度为n的有序序列和m个操作
    第二行有n个数,表示有序序列
    下面有m行,opt表示操作标号
    若opt=1 则为操作1,之后有三个数l,r,k 表示查询k在区间[l,r]的排名
    若opt=2 则为操作2,之后有三个数l,r,k 表示查询区间[l,r]内排名为k的数
    若opt=3 则为操作3,之后有两个数pos,k 表示将pos位置的数修改为k
    若opt=4 则为操作4,之后有三个数l,r,k 表示查询区间[l,r]内k的前驱
    若opt=5 则为操作5,之后有三个数l,r,k 表示查询区间[l,r]内k的后继

    Output

    对于操作1,2,4,5各输出一行,表示查询结果

    Sample Input

    9 6
    4 2 2 1 9 4 0 1 1
    2 1 4 3
    3 4 10
    2 1 4 3
    1 2 5 9
    4 3 9 5
    5 2 8 5

    Sample Output

    2
    4
    3
    4
    9

    HINT

    1.n和m的数据范围:n,m<=50000


    2.序列中每个数的数据范围:[0,1e8]


    3.虽然原题没有,但事实上5操作的k可能为负数
     
     
     
    bzoj上A了,tyvj上被卡时,愣是压了好久没压出来……
    我写的是区间线段树套treap,听说权值线段树套区间线段树在tyvj上可以卡过去,可惜我不会写回收空间,试了一下还是RE了,还是太弱……
    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    using namespace std;
    
    int p,ch,f,ll,rr,mid;
    inline int sread(){
        p=0;ch=getchar();f=1;
        while(ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') p=p*10+ch-48,ch=getchar();
        return p*f;
    }
    inline int read(){
        p=0;ch=getchar();
        while(ch<'0'||ch>'9') ch=getchar();
        while(ch>='0'&&ch<='9') p=p*10+ch-48,ch=getchar();
        return p;
    }
    struct tree{
        int l,r,k,ra,s,w;
        tree(){
            l=r=0;
        }
    }t[1500000];
    int root[200000],l[200000],r[200000];
    int n,m,num=0,a[50001],w,o;
    inline int max(int a,int b){return a>b?a:b;}
    inline int min(int a,int b){return a<b?a:b;}
    inline void ler(int &p){
        int k=t[p].r;
        t[p].r=t[k].l;
        t[k].l=p;
        t[k].s=t[p].s;
        t[p].s=t[p].w+t[t[p].l].s+t[t[p].r].s;
        p=k;
    }
    inline void rir(int &p){
        int k=t[p].l;
        t[p].l=t[k].r;
        t[k].r=p;
        t[k].s=t[p].s;
        t[p].s=t[p].w+t[t[p].l].s+t[t[p].r].s;
        p=k;
    }
    inline void in(int &p,int k){
        if (!p){
            p=++num;
            t[p].k=k;
            t[p].w=t[p].s=1;
            t[p].ra=rand();
            return;
        }
        t[p].s++;
        if (t[p].k==k) t[p].w++;else
        if (t[p].k>k){
            in(t[p].l,k);
            if (t[t[p].l].ra<t[p].ra) rir(p);
        }else{
            in(t[p].r,k);
            if (t[t[p].r].ra<t[p].ra) ler(p);
        }
    }
    inline int que(int p,int k){
        if (!p) return 0;
        if (t[p].k==k){
            w+=t[p].w;
            return t[t[p].l].s;
        }
        if (t[p].k<k) return t[t[p].l].s+t[p].w+que(t[p].r,k);
        return que(t[p].l,k);
    }
    inline void build(int p,int ll,int rr){
        for (register int i=ll;i<=rr;i++) in(root[p],a[i]);
        l[p]=ll;r[p]=rr;
        if (ll<rr){
            int mid=(ll+rr)>>1;
            build(p<<1,ll,mid);
            build((p<<1)|1,mid+1,rr);
        }
    }
    inline int qu(int p,int a,int b,int k){
        if (l[p]==a&&r[p]==b) return que(root[p],k);
        int mid=(l[p]+r[p])>>1;
        if (b<=mid) return qu(p<<1,a,b,k);
        if (a>mid) return qu((p<<1)|1,a,b,k);
        return qu(p<<1,a,mid,k)+qu((p<<1)|1,mid+1,b,k);
    }
    inline void dell(int &p){
        if (!t[p].l&&!t[p].r) p=0;else
        if (!t[p].l) p=t[p].r;else
        if (!t[p].r) p=t[p].l;else
        if (t[t[p].l].ra<t[t[p].r].ra) rir(p),dell(t[p].r);else ler(p),dell(t[p].l);
    }
    inline void del(int &p,int k){
        t[p].s--;
        if (t[p].k==k){
            t[p].w--;
            if (t[p].w==0) dell(p);
            return;
        }
        if (t[p].k<k) del(t[p].r,k);else del(t[p].l,k);
    }
    inline void xdel(int p,int pos){
        del(root[p],a[pos]);
        in(root[p],o);
        if (l[p]==r[p]) return;
        int mid=(l[p]+r[p])>>1;
        if (pos<=mid) xdel(p<<1,pos);else xdel((p<<1)|1,pos);
    }
    inline int qqu(int p,int k){
        if (!p) return -1;
        if (t[p].k>=k) return qqu(t[p].l,k);else{
            int f=qqu(t[p].r,k);
            if (f==-1) return t[p].k;else return f;
        }
    }
    inline int hju(int p,int k){
        if (!p) return 1e9;
        if (t[p].k<=k) return hju(t[p].r,k);else{
            int f=hju(t[p].l,k);
            if (f==1e9) return t[p].k;else return f;
        }
    }
    inline int qq(int p,int a,int b,int k){
        if (l[p]==a&&r[p]==b) return qqu(root[p],k);
        int mid=(l[p]+r[p])>>1;
        if (b<=mid) return qq(p<<1,a,b,k);else
        if (a>mid) return qq((p<<1)|1,a,b,k);else
        return max(qq(p<<1,a,mid,k),qq((p<<1)|1,mid+1,b,k));
    }
    inline int hj(int p,int a,int b,int k){
        if (l[p]==a&&r[p]==b) return hju(root[p],k);
        int mid=(l[p]+r[p])>>1;
        if (b<=mid) return hj(p<<1,a,b,k);else
        if (a>mid) return hj((p<<1)|1,a,b,k);else
        return min(hj(p<<1,a,mid,k),hj((p<<1)|1,mid+1,b,k));
    }
    inline void pr(int a){
       int l=a/10;
       if(l) pr(l);
       putchar(a-l*10+48);
    }
    int main(){
        //freopen("a.in","r",stdin);
        //freopen("a.out","w",stdout);
        n=read();m=read();
        srand(n);
        for (register int i=1;i<=n;i++) a[i]=read();
        build(1,1,n);
        int l,r;
        while(m--){
            o=read();
            if (o==1){
                l=read();r=read();o=read();
                pr(qu(1,l,r,o)+1);putchar('
    ');
            }else if (o==2){
                l=read();r=read();o=read();
                ll=0;rr=1e8;
                while(ll<rr){
                    mid=(ll+rr)>>1;
                    w=0;
                    p=qu(1,l,r,mid);
                    if (p<o&&p+w>=o){
                        ll=mid;
                        break;
                    }
                    if (p>=o) rr=mid-1;else ll=mid+1;
                }
                pr(ll);putchar('
    ');
            }else if (o==3){
                l=read();o=read();
                xdel(1,l);
                a[l]=o;
            }else if (o==4){
                l=read();r=read();o=read();
                pr(qq(1,l,r,o));putchar('
    ');
            }else{
                l=read();r=read();o=sread();
                pr(hj(1,l,r,o));putchar('
    ');
            }
        }
    }
  • 相关阅读:
    EF框架 处理decimal字段 Sum() 遇到NULL时的特殊处理
    RSA加密解密及RSA签名和验证
    SQL 类似switch的东东用法
    js抛物线动画
    MyBatis的结果映射(resultMap)
    mybatis中#和$符号的区别
    MyBatis 中Mapper.xml中注意事项
    MyBatis sql映射器 Mapper
    MyBatis的自定义别名和内置别名
    MyBatis简单认识(入门)
  • 原文地址:https://www.cnblogs.com/Enceladus/p/5220311.html
Copyright © 2011-2022 走看看