动态半凸壳

Splay 维护动态上凸壳

#include <cstdio>
#include <algorithm>

const int MAXN = 1000005;
const double EPS = 1e-9;

int dcmp(double a, double b = 0) {
    double d = a - b;
    return std::abs(d) <= EPS ? 0 : (d > 0 ? 1 : -1);
}

struct Splay {
    struct Node {
        Node *c[2], *fa, *pred, *succ;
        double x, y;

        Node() {}
        Node(Node *fa, double x, double y) : x(x), y(y), c(), fa(fa), pred(NULL), succ(NULL) {}

        int relation() { return fa->c[1] == this; }
    } *root, _pool[MAXN], *_curr;

    Splay() : root(NULL), _curr(_pool) {}

    void rotate(Node *u) {
        Node *o = u->fa;
        int x = u->relation();

        u->fa = o->fa;
        if (u->fa) u->fa->c[o->relation()] = u;

        o->c[x] = u->c[x ^ 1];
        if (u->c[x ^ 1]) u->c[x ^ 1]->fa = o;

        u->c[x ^ 1] = o;
        o->fa = u;
    }

    Node *splay(Node *u, Node *targetFa = NULL) {
        while (u->fa != targetFa) {
            if (u->fa->fa == targetFa) rotate(u);
            else if (u->relation() == u->fa->relation()) rotate(u->fa), rotate(u);
            else rotate(u), rotate(u);
        }
        if (!targetFa) root = u;
        return u;
    }

    double predSlope(Node *u) {
        return u->pred ? (u->y - u->pred->y) / (u->x - u->pred->x) : 1.0 / 0.0;
    }

    double succSlope(Node *u) {
        return u->succ ? (u->y - u->succ->y) / (u->x - u->succ->x) : -1.0 / 0.0;
    }

    Node *insert(double x, double y) {
        if (!root) {
            root = new (_curr++) Node(NULL, x, y);
            return root;
        }

        Node **u = &root, *fa = NULL;

        while (*u && dcmp(x, (*u)->x)) {
            fa = *u;
            u = &(*u)->c[dcmp(x, (*u)->x) > 0];
        }

        if (*u) {
            if (dcmp((*u)->y, y) >= 0) return splay(*u);
            (*u)->y = y;
        } else {
            (*u) = new (_curr++) Node(fa, x, y);

            if ((*u)->relation()) {
                (*u)->succ = fa->succ;
                (*u)->pred = fa;
                if (fa->succ) fa->succ->pred = *u;
                fa->succ = *u;
            } else {
                (*u)->pred = fa->pred;
                (*u)->succ = fa;
                if (fa->pred) fa->pred->succ = *u;
                fa->pred = *u;
            }
        }

        Node *v = *u;
        if (dcmp(predSlope(v), succSlope(v)) <= 0) {
            splay(v->pred);
            splay(v->succ, v->pred);
            v->pred->succ = v->succ;
            v->succ->pred = v->pred;
            v->succ->c[0] = NULL;
            return NULL;
        }

        while (v->pred && dcmp(predSlope(v->pred), predSlope(v)) <= 0)
            v->pred = v->pred->pred;
        if (v->pred) {
            splay(v->pred);
            splay(v, v->pred);
            v->pred->succ = v;
        }
        v->c[0] = NULL;

        while (v->succ && dcmp(succSlope(v->succ), succSlope(v)) >= 0)
            v->succ = v->succ->succ;
        if (v->succ) {
            splay(v->succ);
            splay(v, v->succ);
            v->succ->pred = v;
        }
        v->c[1] = NULL;

        return splay(v);
    }

    Node *find(double slope) {
        Node *u = root;
        while (true) {
            if (dcmp(predSlope(u), slope) < 0) u = u->c[0];
            else if (dcmp(succSlope(u), slope) > 0) u = u->c[1];
            else return u;
        }
    }
} splay;

int main() {

    return 0;
}

results matching ""

    No results matching ""