• P3369 【模板】普通平衡树


    题面

    https://www.luogu.org/problem/P3369

    题解

    #include<cstdio>
    #include<iostream>
    #include<ctime>
    #include<cstdlib>
    using namespace std;
    const int INF=1e8;
    
    struct node{
      node *ch[2],*fa;
      int val,pri,cnt,size;
    } root;
    
    int n,rank,pre,suc;
    
    bool fsr(node *x){
      return (x->fa->ch[1]!=NULL && x->fa->ch[1]==x);
    }
    
    void rotate(node *x){
      int opt;
      node *y=x->fa;
      opt=fsr(x);
      y->ch[opt]=x->ch[1^opt];
      if (x->ch[1^opt]!=NULL) x->ch[1^opt]->fa=y;
      x->fa=y->fa; 
      y->fa->ch[fsr(y)]=x;
      y->fa=x; 
      x->ch[1^opt]=y;
    
      y->size=y->cnt;
      if (y->ch[0]!=NULL) y->size+=y->ch[0]->size;
      if (y->ch[1]!=NULL) y->size+=y->ch[1]->size;
    
      x->size=x->cnt;
      x->size+=y->size;
      if (x->ch[opt]!=NULL) x->size+=x->ch[opt]->size;
    }
    
    void up(node *x) {
      while (x->pri>x->fa->pri) rotate(x);
    }
    
    void down(node* x){
      while (x->ch[0]!=NULL && x->ch[1]!=NULL) {
        if (x->ch[0]->pri>x->ch[1]->pri) rotate(x->ch[0]); 
        else rotate(x->ch[1]);
      }
      if (x->ch[0]==NULL && x->ch[1]==NULL) x->fa->ch[fsr(x)]=NULL;
        else if (x->ch[0]==NULL) x->fa->ch[fsr(x)]=x->ch[1],x->ch[1]->fa=x->fa;
        else x->fa->ch[fsr(x)]=x->ch[0],x->ch[0]->fa=x->fa;
    }
    
    void insert(node *now,int x){
      now->size++;
      if (now->val==x) {
        now->cnt++;
        return;
      }
      if (now->ch[now->val>x]==NULL) {
        node *s=new node();
        s->fa=now;
        s->val=x;
        s->pri=rand()%INF;
        s->cnt=1;
        s->size=1;
        now->ch[now->val>x]=s;
        up(s);
        return;
      }
      else insert(now->ch[now->val>x],x);
    }
    
    void erase(node *now,int x) {
      if (now==NULL) return;
      now->size--;
      if (now->val==x) {
        now->cnt--;
        if (now->cnt==0) down(now);
      }
      else
        erase(now->ch[x<now->val],x);
    }
    
    void dfs(node *x){
      if (x->ch[0]!=NULL) dfs(x->ch[0]);
      printf("val=%d cnt=%d
    ",x->val,x->cnt);
      if (x->ch[1]!=NULL) dfs(x->ch[1]);
    }
    
    void findrank(node *now,int x) {
      if (now->val>x) {
        if (now->ch[1]==NULL) return; else findrank(now->ch[1],x); 
      }
      else {
        if (now->ch[1]!=NULL) rank+=now->ch[1]->size;
        if (now->val==x) {rank++;return;}
        rank+=now->cnt;
        if (now->ch[0]==NULL) return; else findrank(now->ch[0],x);
      }
    }
    
    int findbyrank(node *now,int x){
      int le;
      if (now->ch[1]==NULL) le=0; else le=now->ch[1]->size;
      if (rank+le<=x && x<rank+le+now->cnt) return now->val;
      if (x<rank+le) {
        if (now->ch[1]==NULL) return -1; else return findbyrank(now->ch[1],x);
      }
      else {
        rank+=le+now->cnt;
        if (now->ch[0]==NULL) return -1; else return findbyrank(now->ch[0],x);
      }
    }
    
    void findpre(node *now,int x){
      if (now->val<x) {
        pre=max(now->val,pre);
        if (now->ch[0]==NULL) return; else findpre(now->ch[0],x);
      }
      else {
        if (now->ch[1]==NULL) return; else findpre(now->ch[1],x);
      }
    }
    
    void findsuc(node *now,int x){
      if (now->val>x) {
        suc=min(now->val,suc);
        if (now->ch[1]==NULL) return; else findsuc(now->ch[1],x);
      }
      else {
        if (now->ch[0]==NULL) return; else findsuc(now->ch[0],x);
      }
    }
    
    int main(){
      int i,opt,x;
      scanf("%d",&n);
      root.val=-INF; root.pri=INF; root.cnt=1; root.size=1;
      srand(time(0));
      for (i=1;i<=n;i++) {
        scanf("%d %d",&opt,&x);
        if (opt==1) insert(&root,x);
        if (opt==2) erase(&root,x);
        if (opt==3) {
          rank=0;
          findrank(&root,x);
          printf("%d
    ",rank-1);
        }
        if (opt==4) {
          rank=0;
          printf("%d
    ",findbyrank(&root,x));
        }
        if (opt==5) {
          pre=-INF;
          findpre(&root,x);
          printf("%d
    ",pre);
        }
        if (opt==6) {
          suc=INF;
          findsuc(&root,x);
          printf("%d
    ",suc);
        }
        //dfs(&root);
        //printf("
    ");
      }
      return 0;
    }
  • 相关阅读:
    LinkedHashSet的实现原理
    HashSet的实现原理
    HashMap的实现原理
    pl/sql 笔记之存储过程、函数、包、触发器(下)
    pl/sql 笔记之基础(上)
    第三方网站微信登录实现
    kafka connect 创建、删除连接器connector(非常重要!!!!)
    Kafka Connect JDBC-Source 源连接器配置属性
    kafka connect(非常重要)
    kafka connect 使用说明
  • 原文地址:https://www.cnblogs.com/shxnb666/p/11427368.html
Copyright © 2020-2023  润新知