1 条题解

  • 0
    @ 2026-8-17 23:47:42
    
    
    // Splay 提醒:开启 O2 优化
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    #define N 200005
    #define INF 2147483647
    #define ls(x) tr[x].s[0]
    #define rs(x) tr[x].s[1]
    struct node{
      int s[2], p;
      int v, siz;
      void init(int p1, int v1){
        p=p1; v=v1; siz=1;
      }
    }tr[N*40];
    int n, m, w[N], idx;
    
    inline void pushup(int x){
      tr[x].siz=tr[ls(x)].siz+tr[rs(x)].siz+1;
    }
    inline void rotate(int x){
      int y=tr[x].p,z=tr[y].p;
      int k=tr[y].s[1]==x;
      tr[z].s[tr[z].s[1]==y]=x, tr[x].p=z;
      tr[y].s[k]=tr[x].s[k^1], tr[tr[x].s[k^1]].p=y;
      tr[x].s[k^1]=y, tr[y].p=x;
      pushup(y), pushup(x);
    }
    inline void splay(int &root,int x,int k){
      while(tr[x].p != k){
        int y=tr[x].p,z=tr[y].p;
        if(z != k)
          if((rs(y)==x)^(rs(z)==y)) rotate(x);
          else rotate(y);
        rotate(x);
      }
      if(!k) root=x;
    }
    inline void insert(int &root,int v){
      int u=root,p=0;
      while(u) p=u,u=tr[u].s[v>tr[u].v];
      u = ++idx;
      tr[p].s[v>tr[p].v]=u;
      tr[u].init(p,v);
      splay(root,u,0);
    }
    inline void del(int &root,int v){
      int u=root;
      while(u){
        if(tr[u].v==v) break;
        if(tr[u].v<v) u=rs(u);
        else u=ls(u);
      }
      splay(root,u,0);
      int l=ls(u),r=rs(u);
      while(rs(l)) l=rs(l);
      while(ls(r)) r=ls(r);
      splay(root,l,0);
      splay(root,r,l);
      ls(r)=0;
      splay(root,r,0);
    }
    inline int getrank(int root,int v){
      int u=root,res=0;
      while(u){
        if(tr[u].v<v) 
          res+=tr[ls(u)].siz+1,u=rs(u);
        else u=ls(u);
      }
      return res;
    }
    inline int getpre(int root,int v){
      int u=root,res=-INF;
      while(u){
        if(tr[u].v<v) 
          res=tr[u].v,u=rs(u);
        else u=ls(u);
      }
      return res;
    }
    inline int getnxt(int root,int v){
      int u=root,res=INF;
      while(u){
        if(tr[u].v>v) 
          res=tr[u].v,u=ls(u);
        else u=rs(u);
      }
      return res;
    }
    
    //////////线段树
    #define lc u<<1
    #define rc u<<1|1
    int root[N*4];
    
    void build(int u,int l,int r){
      insert(root[u],-INF), insert(root[u],INF);
      for(int i=l;i<=r;i++)insert(root[u],w[i]);
      if(l==r) return;
      int mid=l+r>>1;
      build(lc,l,mid);
      build(rc,mid+1,r);
    }
    int queryrank(int u,int l,int r,int x,int y,int v){
      if(x<=l && r<=y) return getrank(root[u],v)-1;
      int mid=l+r>>1, res=0;
      if(x<=mid) res += queryrank(lc,l,mid,x,y,v);
      if(y>mid) res += queryrank(rc,mid+1,r,x,y,v);
      return res;
    }
    int queryval(int u,int x,int y,int k){
      int l=0, r=1e8, ans; //二分
      while(l<=r){
        int mid=l+r>>1;
        if(queryrank(1,1,n,x,y,mid)+1<=k) 
          l=mid+1, ans=mid;
        else r=mid-1;
      }
      return ans;
    }
    void change(int u,int l,int r,int pos,int v){
      del(root[u],w[pos]);
      insert(root[u],v);
      if(l==r) return;
      int mid=l+r>>1;
      if(pos<=mid) change(lc,l,mid,pos,v);
      else change(rc,mid+1,r,pos,v);
    }
    int querypre(int u,int l,int r,int x,int y,int v){
      if(x<=l && r<=y) return getpre(root[u],v);
      int mid=l+r>>1, res=-INF;
      if(x<=mid) res=max(res,querypre(lc,l,mid,x,y,v));
      if(y>mid) res=max(res,querypre(rc,mid+1,r,x,y,v));
      return res;
    }
    int querynxt(int u,int l,int r,int x,int y,int v){
      if(x<=l && r<=y) return getnxt(root[u],v);
      int mid=l+r>>1, res=INF;
      if(x<=mid) res=min(res,querynxt(lc,l,mid,x,y,v));
      if(y>mid) res=min(res,querynxt(rc,mid+1,r,x,y,v));
      return res;
    }
    int main(){
      scanf("%d%d",&n,&m);
      for(int i=1;i<=n;i++) scanf("%d",&w[i]);
      build(1,1,n);
      while(m -- ){
        int op,x,y,v;
        scanf("%d",&op);
        if(op==3)scanf("%d%d",&x,&v);
        else scanf("%d%d%d",&x,&y,&v);
        if(op==1)
          printf("%d\n",queryrank(1,1,n,x,y,v)+1);
        if(op==2) 
          printf("%d\n",queryval(1,x,y,v));
        if(op==3)
          change(1,1,n,x,v), w[x]=v;
        if(op==4)
          printf("%d\n",querypre(1,1,n,x,y,v));
        if(op==5)
          printf("%d\n",querynxt(1,1,n,x,y,v));
      }
      return 0;
    }
    
    • 1

    信息

    ID
    12644
    时间
    6000ms
    内存
    2500MiB
    难度
    10
    标签
    递交数
    4
    已通过
    1
    上传者