loj #106. 二逼平衡树

摘要:
#106.二逼平衡树内存限制:512MiB时间限制:4000ms标准输入输出题目类型:传统评测方式:文本比较题目描述这是一道模板题。第二行有n个数,表示有序序列。样例样例输入96422194011214334102143125943955285样例输出24349数据范围与提示1≤n,m≤5e41e8≤k,x≤1e8#include#defineptch[ch[root][1]][0]constintMAXN=1e5+10;constintinf=1e8+10;usingnamespacestd;intn;intch[MAXN˂˂7][2],size[MAXN˂˂7],pre[MAXN˂˂7],key[MAXN˂˂7],cnt2=0,psize;intrt[MAXN],a[MAXN];vectorvec;voidTreavel{if{Treavel;printf;Treavel;}}voiddebug{printf;Treavel;}typedefstructnode{introot,maxx;voidnewnode{x=++cnt2;ch[x][0]=ch[x][1]=0;pre[x]=fa;key[x]=vul;size[x]=1;}voidinte(){root=0;newnode;newnode;}voidup{size[x]=size[ch[x][0]]+size[ch[x][1]]+1;}voidrotate{inty=pre[x];ch[y][!
#106. 二逼平衡树
内存限制:512 MiB时间限制:4000 ms标准输入输出
题目类型:传统评测方式:文本比较
题目描述

这是一道模板题。

您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:

  1. 查询x 在区间内的排名;
  2. 查询区间内排名为k 的值;
  3. 修改某一位置上的数值;
  4. 查询x 在区间内的前趋(前趋定义为小于x,且最大的数);
  5. 查询x 在区间内的后继(后继定义为大于x ,且最小的数)。

输入格式

第一行两个数n,m,表示长度为n的有序序列和m个操作。
第二行有n个数,表示有序序列。

下面有m行,每行第一个数表示操作类型:

  1. 之后有三个数l,r,x表示查询x在区间[l,r]的排名;
  2. 之后有三个数l,r,k表示查询区间[l,r] 内排名为k 的数;
  3. 之后有两个数pos,x表示将pos位置的数修改为x
  4. 之后有三个数l,r,x表示查询区间[l,r]x的前趋;
  5. 之后有三个数l,r,x表示查询区间[l,r] x的后继.

输出格式

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

样例

样例输入

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

样例输出

2
4
3
4
9

数据范围与提示

1≤n,m≤5e4−1e8≤k,x≤1e8

#include <bits/stdc++.h>
#define pt ch[ch[root][1]][0]
const int MAXN=1e5+10;
const int inf=1e8+10;
using namespace std;
int n;
int ch[MAXN<<7][2],size[MAXN<<7],pre[MAXN<<7],key[MAXN<<7],cnt2=0,psize;
int rt[MAXN],a[MAXN];
vector<int>vec;
void Treavel(int x)
{
    if(x)
    {
        Treavel(ch[x][0]);
        printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size=%2d,key=%2d
",x,ch[x][0],ch[x][1],pre[x],size[x],key[x]);
        Treavel(ch[x][1]);
    }
}
void debug(int rp)
{
    printf("root:%d
",rp);
    Treavel(rp);
}
typedef struct node{
    int root,maxx;
    void newnode(int &x,int fa,int vul){
        x=++cnt2;ch[x][0]=ch[x][1]=0;pre[x]=fa;key[x]=vul;
        size[x]=1;
    }
    void inte(){
        root=0;
        newnode(root,0,-inf);
        newnode(ch[root][1],root,inf);
    }
    void up(int x){size[x]=size[ch[x][0]]+size[ch[x][1]]+1;}
    void rotate(int x,int kind){
        int y=pre[x];
        ch[y][!kind]=ch[x][kind];pre[ch[x][kind]]=y;
        if(pre[y]) ch[pre[y]][ch[pre[y]][1]==y]=x;
        pre[x]=pre[y];ch[x][kind]=y;pre[y]=x;
        up(y);
    }
    void splay(int x,int goal){
        while(pre[x]!=goal){
            if(pre[pre[x]]==goal) rotate(x,ch[pre[x]][0]==x);
            else{
                int y=pre[x];int kind=ch[pre[y]][0]==y;
                if(ch[y][kind]==x) rotate(x,!kind),rotate(x,kind);
                else rotate(y,kind),rotate(x,kind);
            }
        }
        if(goal==0) root=x;
        up(x);
    }
    void insert(int &x,int vul,int fa){
        if(!x){newnode(x,fa,vul);return ;}
        if(key[x]>vul) insert(ch[x][0],vul,x);
        else insert(ch[x][1],vul,x);
        up(x);
    }
    int find1(int x,int vul){
        if(key[x]==vul) return x;
        else if(key[x]<vul) return find1(ch[x][1],vul);
        else return find1(ch[x][0],vul);
    }
    int find2(int x,int siz){
        if(siz==size[ch[x][0]]+1) return x;
        else if(siz<=size[ch[x][0]]) return find2(ch[x][0],siz);
        else return find2(ch[x][1],siz-size[ch[x][0]]-1);
    }
    void erase(int vul){
        splay(find1(root,vul),0);
        int t=size[ch[root][0]]+1;
        splay(find2(root,t-1),0);
        splay(find2(root,t+1),root);
        pre[ch[ch[root][1]][0]]=0;ch[ch[root][1]][0]=0;up(ch[root][1]);up(root);
    }
    void pre_vul(int x,int vul){
        if(!x) return ;
        if(key[x]>=vul) pre_vul(ch[x][0],vul);
        else{
            if(vul-key[x]<=vul-maxx) maxx=key[x],pre_vul(ch[x][1],vul);
            else pre_vul(ch[x][1],vul);
        }
    }
    void last_vul(int x,int vul){
        if(!x) return ;
        if(key[x]<=vul) last_vul(ch[x][1],vul);
        else{
            if(key[x]-vul<=maxx-vul) maxx=key[x],last_vul(ch[x][0],vul);
            else last_vul(ch[x][0],vul);
        }
    }
}node;
typedef struct wjy{
   int l,r,sum;
}wjy;
wjy dd[MAXN<<7];int cnt1=0;
typedef struct List{
    node T;
}List;
List d[MAXN<<2];
void built(int &x,int y,int l,int r,int vul,int flag){
    x=++cnt1;dd[x]=dd[y];dd[x].sum+=flag;
    if(l==r) return ;
    int mid=(l+r)>>1;
    if(vul<=mid) built(dd[x].l,dd[y].l,l,mid,vul,flag);
    else built(dd[x].r,dd[y].r,mid+1,r,vul,flag);
}
int ans;
vector<int>vv1;
vector<int>vv2;
int get_id(int x){return x&(-x);}
void slove(int l,int r){
    for(int i=l-1;i>0;i-=get_id(i)) vv2.push_back(rt[i]);
    for(int i=r;i>0;i-=get_id(i)) vv1.push_back(rt[i]);
}
int querty1(int l,int r,int ql,int qr,int vul){
    slove(ql,qr);
    while(l<r){
        int mid=(l+r)>>1;
        if(mid<=vul){
            l=mid+1;
            for(int i=0;i<vv1.size();i++) ans+=dd[dd[vv1[i]].l].sum;
            for(int i=0;i<vv2.size();i++) ans-=dd[dd[vv2[i]].l].sum;
            for(int i=0;i<vv1.size();i++) vv1[i]=dd[vv1[i]].r;
            for(int i=0;i<vv2.size();i++) vv2[i]=dd[vv2[i]].r;
        }
        else{
            r=mid;
            for(int i=0;i<vv1.size();i++) vv1[i]=dd[vv1[i]].l;
            for(int i=0;i<vv2.size();i++) vv2[i]=dd[vv2[i]].l;
        }

    }
    return ans;
}
int querty2(int l,int r,int ql,int qr,int k){
    slove(ql,qr);
    int t;
    while(l<r){
        int mid=(l+r)>>1;t=0;
        for(int i=0;i<vv1.size();i++) t+=dd[dd[vv1[i]].l].sum;
        for(int i=0;i<vv2.size();i++) t-=dd[dd[vv2[i]].l].sum;
        if(t>=k){
            r=mid;
            for(int i=0;i<vv1.size();i++) vv1[i]=dd[vv1[i]].l;
            for(int i=0;i<vv2.size();i++) vv2[i]=dd[vv2[i]].l;
        }
        else{
            l=mid+1;k-=t;
            for(int i=0;i<vv1.size();i++) vv1[i]=dd[vv1[i]].r;
            for(int i=0;i<vv2.size();i++) vv2[i]=dd[vv2[i]].r;
        }

    }
    return l;
}
void update1(int root,int l,int r,int vul,int t,int flag){
    //cout<<l<<" "<<r<<endl;
    //cout<<d[root].T.root<<endl;
    if(flag) d[root].T.insert(d[root].T.root,vul,0);
    else d[root].T.erase(vul);
    //if(!flag) debug(d[root].T.root);
    if(l==r)   return ;
    int mid=(l+r)>>1;
    if(t<=mid) update1(root<<1,l,mid,vul,t,flag);
    else update1(root<<1|1,mid+1,r,vul,t,flag);
}
int maxn;
void querty(int root,int l,int r,int ql,int qr,int x,int flag){
    if(ql<=l&&r<=qr){
        if(flag) d[root].T.maxx=-1*inf,d[root].T.pre_vul(d[root].T.root,x),maxn=max(maxn,d[root].T.maxx);
        else d[root].T.maxx=inf,d[root].T.last_vul(d[root].T.root,x),maxn=min(maxn,d[root].T.maxx);
        return ;
    }
    int mid=(l+r)>>1;
    if(ql<=mid) querty(root<<1,l,mid,ql,qr,x,flag);
    if(qr>mid) querty(root<<1|1,mid+1,r,ql,qr,x,flag);
}
void inte(){
    for(int i=1;i<=(n<<2);i++) d[i].T.inte();
    for(int i=1;i<=n;i++){
        for(int j=i;j<=n;j+=get_id(j)){
            built(rt[j],rt[j],1,psize,a[i],1);

        }
        update1(1,1,n,a[i],i,1);
    }
}
void update(int pos,int x,int y){
    for(int j=pos;j<=n;j+=get_id(j)){
        built(rt[j],rt[j],1,psize,x,-1);
        built(rt[j],rt[j],1,psize,y,1);
    }
    update1(1,1,n,x,pos,0);
    //cout<<"sb"<<endl;
    update1(1,1,n,y,pos,1);
    //cout<<"sb"<<endl;
}
int slove1(int l,int r,int x){
    ans=0;
    int ans1=querty1(1,psize,l,r,x-1);
    vv1.clear();vv2.clear();
    return ans1+1;
}
int slove2(int l,int r,int k){
    ans=querty2(1,psize,l,r,k);
    vv1.clear();vv2.clear();
    return ans;
}
int slove3(int l,int r,int x){
    maxn=-1*inf;querty(1,1,n,l,r,x,1);
    return maxn;
}
int slove4(int l,int r,int x){
    //cout<<l<<" "<<r<<endl;
    maxn=inf;querty(1,1,n,l,r,x,0);
    return maxn;
}
typedef struct P{
  int op,l,r,x;
}P;
P p[MAXN];
int main(){
    int m;scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]),vec.push_back(a[i]);
    for(int i=1;i<=m;i++){
        scanf("%d",&p[i].op);
        if(p[i].op==3) scanf("%d%d",&p[i].l,&p[i].x),vec.push_back(p[i].x);
        else if(p[i].op==2) scanf("%d%d%d",&p[i].l,&p[i].r,&p[i].x);
        else scanf("%d%d%d",&p[i].l,&p[i].r,&p[i].x),vec.push_back(p[i].x);
    }
    sort(vec.begin(),vec.end());
    psize=unique(vec.begin(),vec.end())-vec.begin();
    for(int i=1;i<=n;i++) a[i]=lower_bound(vec.begin(),vec.begin()+psize,a[i])-vec.begin()+1;
    inte();
    for(int i=1;i<=m;i++){
        if(p[i].op==2) continue;
        p[i].x=lower_bound(vec.begin(),vec.begin()+psize,p[i].x)-vec.begin()+1;
    }
    for(int i=1;i<=m;i++){
        if(p[i].op==1) printf("%d
",slove1(p[i].l,p[i].r,p[i].x));
        else if(p[i].op==2) printf("%d
",vec[slove2(p[i].l,p[i].r,p[i].x)-1]);
        else if(p[i].op==3) update(p[i].l,a[p[i].l],p[i].x),a[p[i].l]=p[i].x;
        else if(p[i].op==4) printf("%d
",vec[slove3(p[i].l,p[i].r,p[i].x)-1]);
        else printf("%d
",vec[slove4(p[i].l,p[i].r,p[i].x)-1]);
    }
    return 0;
}

免责声明:文章转载自《loj #106. 二逼平衡树》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Java中public,private,protected,和默认的区别关联,依赖,泛化(又称继承分为扩展或包含),实现,聚合(共享),复合(组合)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

随便看看

apk反编译与破解

以前版本的bat的名称可能有点不同。)获取d2j-dex2jar.bat目录中的classs-dex2jar.car文件,然后使用jd_GUI工具打开jar文件以查看java源代码。...

故障排查:vsftpd无法用浏览器访问

CentOS6上设置的ftp服务器突然无法使用浏览器访问,但可以使用xftp等工具正常访问。据推测,阿里云的安全组设置之前已经过修改,这可能与1)修改vsftpd的配置,在被动模式下手动指定一个随机连接端口,并添加以下内容:passv_min_port=50000pasv_max_port=60000 02)如果只打开端口20和21,设置阿里云安全组控制端口...

mini.DataGrid使用说明

√√√ ajaxOptionsObjectajax配置对象。√√√ idFieldString是行数据的唯一字段。设置为“client”之后,客户端将排序√√√√ totalCountNumber记录总数√√√ defaultColumnWidthNumber默认列宽100√√√√ showColumnsBoolean显示标头true√√√√ showPag...

Android:在任务列表隐藏最近打开的app

//schemas.android.com/apk/res/android“package=”com.li.test“android:versionName=”1.0“&gt:targetSdkVersion=”23“/&gt:allowBackup=”true“android:icon=”@mipmap/ic_launcher“androi...

oracle触发器调试

如果触发器执行成功,不会出现第4个图,不成功,会出现数据调试信息,具体报错位置会定位到。F7单步执行4.出错时,会出现调试数据,双击调试数据,可以复制出来...

安装samba服务器实现Linux mint和Windows共享文件

安装samba服务器以实现Linuxmint和Windows共享文件。在Linuxmint普通用户下执行命令:sudoapt-geinstallsamba、installsamba和打开smb。conf配置文件,并执行命令gedit/etc/samba/smb-Coff,如果您想安装gedit(sudoapt-geinstallgedit),还可以使用Lin...