zoukankan      html  css  js  c++  java
  • [bzoj3196]Tyvj 1730 二逼平衡树

    来自FallDream的博客,未经允许,请勿转载。


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

    n,m<=50000   1s/128MB

    这道题我是不知道怎么做 传统的动态区间k大都可以实现这些操作 但是

    线段树套权值线段树:时间nlog^2n 空间nlog^2n 这道题空间卡成这样 理论上讲是不够的

    线段树套平衡树 空间只有nlogn 但是时间nlog^3n 这居然能过????

    不管  数据水,所以上面两个都能过  比较好奇出题人写的啥优秀做法。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #define MV 10000000
    #define MN 50000
    #define N 65536
    using namespace std;
    inline int read()
    {
        int x = 0 , f = 1; char ch = getchar();
        while(ch < '0' || ch > '9'){ if(ch == '-') f = -1;  ch = getchar();}
        while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}
        return x * f;
    }
    struct ques{int op,l,r,x;}q[MN+5];
    struct Tree{int l,r,x;}T[MV];
    int n,m,rt[N*2+5],a[MN+5],tot,cnt=0,J=1,l[MN*2+5],R[MN+5],rtnum;
    
    void Add(int x,int lt,int rt,int v,int ad)
    { 
        T[x].x+=ad;
        if(lt==rt) return;
        int mid=lt+rt>>1;
        if(v<=mid) Add(!T[x].l?T[x].l=++cnt:T[x].l,lt,mid,v,ad);
        else Add(!T[x].r?T[x].r=++cnt:T[x].r,mid+1,rt,v,ad); 
    }
    void Modify(int x,int v,int ad){for(x+=N;x;x>>=1) Add(rt[x],1,J,v,ad);}
    
    void GetRt(int l,int r)
    {
        for(rtnum=0,l+=N-1,r+=N+1;l^r^1;l>>=1,r>>=1)
        {
            if(~l&1) R[++rtnum]=rt[l+1];
            if( r&1) R[++rtnum]=rt[r-1];
        }
    }
    
    int GetRk(int v)
    {
        if(!v) return 1;
        int l=1,r=J,mid,ans=1;
        while(l<r)
        {
            mid=l+r>>1;
            if(v<=mid)
            {
                r=mid;
                for(int j=1;j<=rtnum;++j) R[j]=T[R[j]].l; 
            }
            else
            {
                l=mid+1;
                for(int j=1;j<=rtnum;++j) ans+=T[T[R[j]].l].x,R[j]=T[R[j]].r; 
            } 
        }
        for(int j=1;j<=rtnum;++j) ans+=T[R[j]].x;
        return ans;
    }
    
    int GetNum(int rk)
    {
        int l=1,r=J,mid,sum;
        while(l<r)
        {
            mid=l+r>>1;sum=0;
            for(int i=1;i<=rtnum;++i)
                sum+=T[T[R[i]].l].x;
            if(sum<rk) 
            {
                rk-=sum;l=mid+1;
                for(int i=1;i<=rtnum;++i) R[i]=T[R[i]].r; 
            }
            else
            {
                r=mid;
                for(int i=1;i<=rtnum;++i) R[i]=T[R[i]].l;    
            }
        }
        return l;
    }
    
    int main()
    {
        tot=n=read();m=read();
        for(int i=1;i<=N<<1;++i) rt[i]=++cnt; 
        for(int i=1;i<=n;++i) l[i]=a[i]=read();
        for(int i=1;i<=m;++i)
        {
            q[i].op=read();q[i].l=read();q[i].r=read();
            if(q[i].op!=3) q[i].x=read();
            else l[++tot]=q[i].r;    
        }
        sort(l+1,l+tot+1);
        for(int i=2;i<=tot;++i) if(l[i]!=l[i-1]) l[++J]=l[i]; 
        for(int i=1;i<=n;++i) Modify(i,a[i]=lower_bound(l+1,l+J+1,a[i])-l,1);
        for(int i=1;i<=m;++i)
        {
            if(q[i].op==3)
            {
                Modify(q[i].l,a[q[i].l],-1);
                Modify(q[i].l,q[i].r=lower_bound(l+1,l+J+1,q[i].r)-l,1);
                a[q[i].l]=q[i].r;
            } 
            else 
            {
                GetRt(q[i].l,q[i].r);    
                if(q[i].op==1) printf("%d
    ",GetRk(lower_bound(l+1,l+J+1,q[i].x)-l-1));
                if(q[i].op==2) printf("%d
    ",l[GetNum(q[i].x)]);
                if(q[i].op==4) 
                {
                    int rk=GetRk(lower_bound(l+1,l+J+1,q[i].x)-l-1)-1;
                    GetRt(q[i].l,q[i].r);
                    printf("%d
    ",l[GetNum(rk)]); 
                }
                if(q[i].op==5) 
                {
                    int rk=GetRk(upper_bound(l+1,l+J+1,q[i].x)-l-1); 
                    GetRt(q[i].l,q[i].r);
                    printf("%d
    ",l[GetNum(rk)]); 
                } 
            }
        }
        return 0;
    }
  • 相关阅读:
    vs2010下载
    .Net执行cmd命令
    本Blog链接交换
    DNN 04.09.01 StartKit中的新内容。
    如何使一个你没有源代码的DLL文件变为强命名的(Strong Name)
    "Error Creating Control" when creating a custom control
    GridView导出为Excel后,导出的.xls文件无法作为源文件导入的问题
    DotNetNuke的C#版本
    DotNetNuke 5.0 放到CodePlex上提供下载了
    在VS中使用独立的项目(Project)开发DNN模块
  • 原文地址:https://www.cnblogs.com/FallDream/p/bzoj3196.html
Copyright © 2011-2022 走看看