Skip to content

Commit

Permalink
LCT
Browse files Browse the repository at this point in the history
  • Loading branch information
bqi343 committed Feb 10, 2019
1 parent e386bcc commit 8d2f6c7
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 83 deletions.
Original file line number Diff line number Diff line change
@@ -1,66 +1,48 @@
/**
* Sources: Dhruv Rohatgi,
* https://sites.google.com/site/kc97ble
* /container/splay-tree/splaytree-cpp-3
* Verification: SPOJ DYNACON1, DYNALCA
*/
* Sources: Dhruv Rohatgi,
* https://sites.google.com/site/kc97ble
* /container/splay-tree/splaytree-cpp-3
* Verification: SPOJ DYNACON1, DYNALCA
*/

using namespace splayTree;

template<int SZ> struct LCT {
ps S[SZ];
LCT () { F0R(i,SZ) S[i] = new snode(i); }

// disconnect x from d-th child
void dis(ps x, int d) {
ps y = x->c[d];
if (x) x->c[d] = NULL, recalc(x);
if (y) y->p = NULL, y->pp = x;
}

void con(ps x, int d) { setLink(x->pp,x,d); x->pp = NULL; }

void setPref(ps x) { splay(x->pp), dis(x->pp,1), con(x,1); splay(x); }

ps access(ps x) { // x is brought to the root of auxiliary tree
dis(splay(x),1);
while (x->pp) setPref(x);
return x;
if (y) { y->p = NULL; if (d) y->pp = x; }
}
// set x to be child of pp
void makeChild(ps x) { setLink(x->pp,x,1); x->pp = NULL; }
// unlink x->pp from its preferred child, then set x to be preferred child
void setPref(ps x) { splay(x->pp), dis(x->pp,1), makeChild(x), splay(x); }
// x is brought to the root of auxiliary tree
ps access(ps x) { dis(splay(x),1); while (x->pp) setPref(x); return x; }

//////// UPDATES

ps makeRoot(ps v) { access(v)->flip = 1; return access(v); }

void link(ps v, ps w) {
access(w)->pp = makeRoot(v);
con(w,0);
}

void cut(ps x) { // cut link between x and its parent
ps y = access(x)->c[0];
dis(x,0); y->pp = NULL;
}
// make y the parent of x
void link(ps x, ps y) { makeRoot(x)->pp = y; }
// cut link between x and its parent
void cut(ps x) { dis(access(x),0); }

//////// QUERIES

int getDepth(ps v) { access(v); return getsz(v->c[0]); }

int getRoot(ps v) { return getExtreme(access(v),0)->id; }

int lca(ps x, ps y) {
ps root = getExtreme(access(y),0);

dis(splay(x),1);
auto z = getExtreme(x,0);
if (z == root) return x->val;
splay(x);

while (x->pp) {
auto z = getExtreme(splay(x->pp),0);
if (z == root) return x->pp->val;
setPref(x);
int getDepth(ps x) { access(x); return getsz(x->c[0]); }
ps getRoot(ps x) { return farthest(access(x),0); }
ps lca(ps x, ps y) {
ps root = getRoot(y);
if (farthest(splay(x),0) == root) return x;
while (splay(x)->pp) {
if (farthest(splay(x->pp),0) == root) return x->pp;
setPref(splay(x));
}

return -1;
return NULL;
}
};
Original file line number Diff line number Diff line change
@@ -1,80 +1,71 @@
/**
* Description: Treap alternative
* Source: see LCT
* Verification: ~
*/
* Description: Treap alternative
* Source: see LCT
* Verification: ~
*/

namespace splayTree {
typedef struct snode* ps;

struct snode {
int val; ps p, pp, c[2]; // essential
int sz; // # nodes in subtree
bool flip; // range flip
int val, sz; // value, # nodes in subtree
ps p, pp, c[2]; // parent, path-parent (for LCT), children
bool flip; // for range flip

snode (int _val) {
val = _val; c[0] = c[1] = p = pp = NULL;
sz = 1; flip = 0;
snode (int val) : val(val) {
sz = 1;
p = pp = c[0] = c[1] = NULL;
flip = 0;
}
};

int getsz(ps x) { return x?x->sz:0; }
int getDir(ps x, ps y) { return x?(x->c[1] == y):-1; }

void trav(ps x, vi& v) {
if (!x) return;
trav(x->c[0],v); v.pb(x->val); trav(x->c[1],v);
}

int getsz(ps x) { return x ? x->sz : 0; }
int dir(ps x, ps y) { return x ? (x->c[1] == y) : -1; }
ps recalc(ps x) {
x->sz = 1+getsz(x->c[0])+getsz(x->c[1]);
return x;
}

void setLink(ps x, ps y, int d) { // x propagated
if (x) x->c[d] = y, recalc(x);
if (y) y->p = x;
}

void prop(ps x) {
if (!x || !x->flip) return;
swap(x->c[0],x->c[1]);
if (x->c[0]) x->c[0]->flip ^= 1;
if (x->c[1]) x->c[1]->flip ^= 1;
x->flip = 0;
}

void pushDown(ps x) {
void propAnc(ps x) { // propagate ancestors
if (!x) return;
if (x->p) pushDown(x->p);
if (x->p) propAnc(x->p);
prop(x);
}
void tour(ps x, vi& v) {
if (!x) return;
tour(x->c[0],v); v.pb(x->val); tour(x->c[1],v);
}

void setLink(ps x, ps y, int d) { // x propagated
if (x) x->c[d] = y, recalc(x);
if (y) y->p = x;
}
void rot(ps x, int d) { // precondition: x & parents propagated
snode *y = x->c[d], *z = x->p;
prop(y);
ps y = x->c[d], z = x->p; prop(y);
setLink(x, y->c[d^1], d);
setLink(y, x, d^1);
setLink(z, y, getDir(z, x));
y->pp = x->pp; x->pp = NULL;
setLink(z, y, dir(z, x));
y->pp = x->pp; x->pp = NULL; // set y to be parent of x
}

ps splay(ps x) {
pushDown(x);
propAnc(x);
while (x && x->p) {
ps y = x->p, z = y->p;
int dy = getDir(y, x), dz = getDir(z, y);
int dy = dir(y, x), dz = dir(z, y);
if (!z) rot(y, dy);
else if (dy == dz) rot(z, dz), rot(y, dy);
else rot(y, dy), rot(z, dz);
}
return x;
}

ps getExtreme(ps x, int d) { // get leftmost or rightmost node
prop(x);
if (x->c[d]) return getExtreme(x->c[d],d);
return splay(x);
ps farthest(ps x, int d) { // get leftmost or rightmost node
prop(x); return x->c[d]?farthest(x->c[d],d):splay(x);
}
}

Expand Down

0 comments on commit 8d2f6c7

Please sign in to comment.