JOYOI1728 普通平衡树(Splay)

原创 2018年04月15日 15:56:30

题意分析

Splay 模板题,理解了好半天,照猫画虎来一发。
我写的这个效率很低啊,跑了400ms。。。

代码总览

#include<bits/stdc++.h>
using namespace std;
const int nmax = 100000<<2;
int ch[nmax][2], f[nmax], cnt[nmax], key[nmax], size[nmax];
int root = 0, sz = 0;
inline void clear(int x) {
    ch[x][0] = ch[x][1] = f[x] = cnt[x] = key[x] = size[x] = 0;
}
inline int get(int x) {
    return ch[f[x]][1] == x;
}
inline void update(int x) {
    if(x){
        size[x] = cnt[x];
        if(ch[x][0]) size[x] += size[ch[x][0]];
        if(ch[x][1]) size[x] += size[ch[x][1]];
    }
}
inline void rotate(int x) {
    int old = f[x], oldf = f[old], which = get(x);
    ch[old][which] = ch[x][which^1]; f[ch[old][which]] = old;
    f[old] = x; ch[x][which^1] = old;
    f[x] = oldf;
    if(oldf) ch[oldf][ch[oldf][1] == old] = x;
    update(old);update(x);
}
inline void splay(int x) {
    for(int fa; fa = f[x]; rotate(x))
        if(f[fa]) rotate((get(x) == get(fa))? fa:x);
    root = x;
}
inline void insert(int v) {
    if(root == 0) {
        sz ++; ch[sz][0] = ch[sz][1] = f[sz] = 0;
        key[sz] = v; cnt[sz] = 1; size[sz] = 1;
        root = sz; return;
    }
    int now = root,  fa = 0;
    while(1) {
        if(key[now] == v) {
            cnt[now] ++; update(now); update(fa);
            splay(now); break;
        }
        fa = now;
        now = ch[now][v > key[now]];
        if(now == 0) {
            sz ++;
            ch[sz][0] = ch[sz][1] = 0; key[sz] = v; size[sz] = 1;
            cnt[sz] = 1; f[sz] = fa; ch[fa][v > key[fa]] = sz;
            update(fa);
            splay(sz);
            break;
        }
    }
}
inline int find(int v) {
    int ans = 0, now = root;
    while(1) {
        if(v < key[now]) now = ch[now][0];
        else {
            ans += (ch[now][0]? size[ch[now][0]]:0);
            if(v == key[now]) {splay(now); return ans + 1;}
            ans += cnt[now];
            now = ch[now][1];
        }
    }
}
inline int findx(int x) {
    int now = root;
    while(1) {
        if(ch[now][0] &&  x<=size[ch[now][0]]) now = ch[now][0];
        else {
            int temp = (ch[now][0]?size[ch[now][0]]:0) + cnt[now];
            if(x <= temp) return key[now];
            x -= temp; now = ch[now][1];
        }
    }
}
inline int pre() {
    int now = ch[root][0];
    while (ch[now][1]) now = ch[now][1];
    return now;
}
inline int next(){
    int now = ch[root][1];
    while (ch[now][0]) now = ch[now][0];
    return now;
}

inline void del(int x){
     int whatever = find(x);
     if (cnt[root]>1) {cnt[root]--;return;}
     if (!ch[root][0]&&!ch[root][1]) {clear(root);root=0;return;}
     if (!ch[root][0]){
          int oldroot=root;root=ch[root][1];f[root]=0;clear(oldroot);return;
     }
     else if (!ch[root][1]){
          int oldroot=root;root=ch[root][0];f[root]=0;clear(oldroot);return;
     }
     int leftbig=pre(),oldroot=root;
     splay(leftbig);
     f[ch[oldroot][1]]=root;
     ch[root][1]=ch[oldroot][1];
     clear(oldroot);
     update(root);
     return;
}
int n,opt,x;
int main(){
    scanf("%d",&n);
    for(int i = 0;i<n;++i){
        scanf("%d %d",&opt,&x);
        if(opt == 1) insert(x);
        else if(opt == 2) del(x);
        else if(opt == 3) printf("%d\n",find(x));
        else if(opt == 4) printf("%d\n",findx(x));
        else if(opt == 5) {
            insert(x); printf("%d\n",key[pre()]); del(x);
        }else if(opt == 6){
            insert(x); printf("%d\n",key[next()]); del(x);
        }
    }
    return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/pengwill97/article/details/79949988

bzoj3224 普通平衡树【splay版】

平衡树模板题。splay版。
  • sdfzyhx
  • sdfzyhx
  • 2016-05-16 23:12:45
  • 1100

BZOJ3223&3224 文艺&普通平衡树 Splay模板(数组)

才发现自己splay的模板又臭又长,还自带大常数,而且指针不会调,换回数组,从新打了一遍 区间翻转:#include #include #include #include #include using...
  • DaD3zZ
  • DaD3zZ
  • 2016-03-22 17:34:39
  • 709

丑的一笔的普通平衡树ver的splay

splay_Flaze ver1.0 常数大的飞起,代码丑得上天 BZOJ 3224 普通平衡树 CodeVS 4543 普通平衡树 从正式开始写平衡树到现在……Flaze码了无数...
  • Flaze_
  • Flaze_
  • 2016-04-15 23:10:45
  • 413

洛谷P3369 普通平衡树(Treap/Splay)

题目描述您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 1. 插入x数 2. 删除x数(若有多个相同的数,因只删除一个) 3. 查询x数的排名(若有多个相同的...
  • Ab_Ever
  • Ab_Ever
  • 2017-04-17 11:50:16
  • 444

BZOJ3224 普通平衡树(splay)

题目在这里 题意:让你实现一棵树,实现 插入, 删除,查询x数的排名,查询排名为x的数 ,求x的前驱(前驱定义为小于x,且最大的数), 求x的后继(后继定义为大于x,且最小的数) 这道题最...
  • glk__
  • glk__
  • 2016-07-16 11:38:37
  • 820

史上最详尽的平衡树(splay)讲解与模板

所有的结局都已写好,所有的泪水也都已启程,却忽然忘了,是怎麽样的一个开始。在那个古老的,不再回来的夏日,无论我如何地去追索,年轻的你只如云影掠过。而你微笑的面容,极浅极淡,逐渐隐没在日落后的群岚。遂翻...
  • Clove_unique
  • Clove_unique
  • 2016-02-03 20:59:45
  • 13644

bzoj3224普通平衡树 Splay

第一次写Splay 憋了一天累觉不爱 网上关于Splay的资料太少了- -|| http://www.cnblogs.com/kuangbin/archive/2013/04/21/3034081...
  • yxr0105
  • yxr0105
  • 2016-05-04 19:52:26
  • 278

bzoj 3224: Tyvj 1728 普通平衡树(splay 模板题)

3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 7756  Solved: 3267 [Submit...
  • clover_hxy
  • clover_hxy
  • 2016-07-13 10:50:34
  • 502

bzoj 3224==tyvj 1728普通平衡树 splay

啊啊啊啊今天各种煞笔啊。。 首先早晨起晚了。。一晚上从11点睡到了7点。。 下午大概三点半开始写这个题。。各种不顺以后发现70分一直超时。。各种方法都不行,后来直接把lyw的子程序都闹过来结果成6...
  • u012457935
  • u012457935
  • 2013-12-05 18:41:09
  • 2269

bzoj 3223 文艺平衡树 Splay详细解析

本文不会过于深入介绍splay的证明,感性认知- -。 对于树我们知道它有两个旋转,对于一个节点,如果它是左儿子,那么它只能右旋,如果它是右儿子,它只能左旋,在splay的时候,我们的目的是把一个节...
  • Kamisama123
  • Kamisama123
  • 2017-07-14 20:51:30
  • 523
收藏助手
不良信息举报
您举报文章:JOYOI1728 普通平衡树(Splay)
举报原因:
原因补充:

(最多只允许输入30个字)