Difference between revisions of "Heap"

From EOJ Wiki
Jump to navigation Jump to search
(Created page with "== Leftist Tree (Persistent) == <syntaxhighlight lang='cpp'> namespace LTree { extern struct P* null, *pit; queue<P*> trash; const int M = 1E6 + 100; struct P...")
 
 
Line 1: Line 1:
 
== Leftist Tree (Persistent) ==
 
== Leftist Tree (Persistent) ==
 
+
持久化可并堆,自带垃圾回收。
 
<syntaxhighlight lang='cpp'>
 
<syntaxhighlight lang='cpp'>
 
namespace LTree {
 
namespace LTree {
Line 10: Line 10:
 
         LL v;
 
         LL v;
 
         int d;
 
         int d;
         void operator delete (void* ptr) {
+
         void operator delete (void* ptr) { trash.push((P*)ptr); }
            trash.push((P*)ptr);
 
        }
 
 
         void* operator new(size_t size) {
 
         void* operator new(size_t size) {
 
             if (trash.empty()) return pit++;
 
             if (trash.empty()) return pit++;
Line 34: Line 32:
 
         return ret;
 
         return ret;
 
     }
 
     }
 +
}
 +
</syntaxhighlight>
 +
 +
== pb_ds ==
 +
 +
如果不需要持久化,只需要值的修改或者堆的合并,那么使用 pb_ds 版本,其中的配对堆足够优秀了。
 +
 +
<syntaxhighlight lang='cpp'>
 +
#include<ext/pb_ds/priority_queue.hpp>
 +
using namespace __gnu_pbds;
 +
 +
typedef __gnu_pbds::priority_queue<LL, less<LL>, pairing_heap_tag> PQ;
 +
__gnu_pbds::priority_queue<int, cmp, pairing_heap_tag>::point_iterator it;
 +
PQ pq, pq2;
 +
 +
int main() {
 +
    auto it = pq.push(2);
 +
    pq.push(3);
 +
    assert(pq.top() == 3);
 +
    pq.modify(it, 4);
 +
    assert(pq.top() == 4);
 +
    pq2.push(5);
 +
    pq.join(pq2);
 +
    assert(pq.top() == 5);
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>

Latest revision as of 12:12, 6 March 2018

Leftist Tree (Persistent)

持久化可并堆,自带垃圾回收。

namespace LTree {
    extern struct P* null, *pit;
    queue<P*> trash;
    const int M = 1E6 + 100;
    struct P {
        P *ls, *rs;
        LL v;
        int d;
        void operator delete (void* ptr) { trash.push((P*)ptr); }
        void* operator new(size_t size) {
            if (trash.empty()) return pit++;
            void* ret = trash.front(); trash.pop(); return ret;
        }
    } pool[M], *pit = pool, *null = new P{0, 0, -1, -1};
    P* N(LL v, P* ls = null, P* rs = null) {
        if (ls->d < rs->d) swap(ls, rs);
        return new P{ls, rs, v, rs->d + 1};
    }
    P* merge(P* a, P* b) {
        if (a == null) return b;
        if (b == null) return a;
        if (a->v < b->v) return N(a->v, a->ls, merge(a->rs, b));
        else return N(b->v, b->ls, merge(b->rs, a));
    }

    LL pop(P*& o) {
        LL ret = o->v;
        o = merge(o->ls, o->rs);
        return ret;
    }
}

pb_ds

如果不需要持久化,只需要值的修改或者堆的合并,那么使用 pb_ds 版本,其中的配对堆足够优秀了。

#include<ext/pb_ds/priority_queue.hpp>
using namespace __gnu_pbds;

typedef __gnu_pbds::priority_queue<LL, less<LL>, pairing_heap_tag> PQ;
__gnu_pbds::priority_queue<int, cmp, pairing_heap_tag>::point_iterator it;
PQ pq, pq2;

int main() {
    auto it = pq.push(2);
    pq.push(3);
    assert(pq.top() == 3);
    pq.modify(it, 4);
    assert(pq.top() == 4);
    pq2.push(5);
    pq.join(pq2);
    assert(pq.top() == 5);
}