• [luogu3369][普通平衡树]


    题目链接

    思路

    模板
    只是有几个容易出错的地方
    第45行容易忘记
    第54行里面的cnt--和siz--容易忘记
    第56行是根据id判断不是val
    第60行siz--容易忘记
    第64行是siz+1不是siz+cnt
    第77行和82行等于的情况容易忽略

    代码

    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<ctime>
    #define ls TR[cur].ch[0]
    #define rs TR[cur].ch[1]
    using namespace std;
    typedef long long ll;
    const int N = 100000 + 100,INF = 1e7 + 100;
    ll read() {
       ll x = 0,f = 1;char c = getchar();
       while(c < '0' || c > '9') {
          if(c == '-') f = -1;
          c = getchar();
       }
       while(c >= '0' && c <= '9') {
          x = x * 10 + c - '0';
          c = getchar();
       }
       return x * f;
    }
    struct node {
       int ch[2],val,id,cnt,siz;
    }TR[N];
    void up(int cur) {
       TR[cur].siz = TR[ls].siz + TR[rs].siz + TR[cur].cnt;
    }
    void rotate(int &cur,int f) {
       int son = TR[cur].ch[f];
       TR[cur].ch[f] = TR[son].ch[f ^ 1];
       TR[son].ch[f ^ 1] = cur;
       up(cur);
       cur = son;
       up(cur);
    }
    int tot;
    void insert(int &cur,int val) {
       if(!cur) {
          cur = ++tot;
          TR[cur].val = val;
          TR[cur].id = rand();
          TR[cur].cnt = TR[cur].siz = 1;
          return;
       }
       TR[cur].siz++;//!!
       if(TR[cur].val == val) { TR[cur].cnt++;return;}
       int d = val > TR[cur].val;
       insert(TR[cur].ch[d],val);
       if(TR[TR[cur].ch[d]].id < TR[cur].id) rotate(cur,d);
    }
    void del(int &cur,int val) {
       if(!cur) return;
       if(val == TR[cur].val) {
          if(TR[cur].cnt > 1) {TR[cur].cnt--;TR[cur].siz--; return;}
          if(!ls || !rs) {cur = ls + rs;return;}
          int d = TR[rs].id < TR[ls].id;
          rotate(cur,d);
          del(cur,val);
       }
       else TR[cur].siz--,del(TR[cur].ch[val > TR[cur].val],val);
    }
    int Rank(int cur,int val) {
       if(!cur) return 0;
       if(val == TR[cur].val) return TR[ls].siz + 1;
       if(val < TR[cur].val) return Rank(ls,val);
       return Rank(rs,val) + TR[ls].siz + TR[cur].cnt;
    }
    int kth(int cur,int now) {
       while(1) {
          if(TR[ls].siz >= now) cur = ls;
          else if(TR[ls].siz + TR[cur].cnt < now) now -=TR[ls].siz + TR[cur].cnt,cur = rs;
          else return TR[cur].val;
       }
    }
    int pred(int cur,int val) {
       if(!cur) return -INF;
       if(val <= TR[cur].val) return pred(ls,val);//!!!
       return max(pred(rs,val),TR[cur].val);
    }
    int nex(int cur,int val) {
       if(!cur) return INF;
       if(val >= TR[cur].val) return nex(rs,val);//!!!
       return min(nex(ls,val),TR[cur].val);
    }
    int main() {
       srand(time(0));
       int n = read();
       int rt = 0;
       while(n--) {
          int opt = read(),x = read();
          if(opt == 1) insert(rt,x);
          if(opt == 2) del(rt,x);
          if(opt == 3) printf("%d
    ",Rank(rt,x));
          if(opt == 4) printf("%d
    ",kth(rt,x));
          if(opt == 5) printf("%d
    ",pred(rt,x));
          if(opt == 6) printf("%d
    ",nex(rt,x));
       }
    
       return 0;
    }
    

    一言

    记忆或会消失,但我的心会记着承诺。

  • 相关阅读:
    python 教程 第十七章、 网络编程
    SecureCRT循环检查设备状态
    《让僵冷的翅膀飞起来》系列之一——从实例谈OOP、工厂模式和重构
    设计,看上去很美!——“Design & Pattern”团队的第一块砖
    杂拌儿
    换了个计数器
    在Remoting客户端激活方式采用替换类以分离接口与实现
    动动手脚,protected不再被保护
    博客园出现在MSDN中国的首页链接
    近期写作计划和读书安排
  • 原文地址:https://www.cnblogs.com/wxyww/p/10041186.html
Copyright © 2020-2023  润新知