后缀自动机(Suffix Automaton)

#include <cstdio>
#include <vector>
#include <algorithm>

const int MAXN = 100005;
const int CHAR_SET = 26;

struct SAM {
    struct Node {
        Node *c[CHAR_SET], *next;
        int max, posCnt;

        Node(int max = 0, bool newSuffix = false) : max(max), posCnt(newSuffix), next(NULL), c() {}

        int min() const {
            return next->max + 1;
        }
    } *start, *last, _pool[MAXN << 1], *_curr;

    SAM() {
        init();
    }

    void init() {
        _curr = _pool;
        start = last = new (_curr++) Node;
    }

    Node *extend(int c) {
        Node *u = new (_curr++) Node(last->max + 1, true), *v = last;

        for (; v && !v->c[c]; v = v->next) v->c[c] = u;

        if (!v) {
            u->next = start;
        } else if (v->c[c]->max == v->max + 1) {
            u->next = v->c[c];
        } else {
            Node *n = new (_curr++) Node(v->max + 1), *o = v->c[c];
            std::copy(o->c, o->c + CHAR_SET, n->c);
            n->next = o->next;
            u->next = o->next = n;
            for (; v && v->c[c] == o; v = v->next) v->c[c] = n;
        }

        return last = u;
    }

    std::vector<Node *> topo;
    std::vector<Node *> toposort() {
        static int buc[MAXN << 1];
        int max = 0;
        for (Node *p = _pool; p != _curr; p++) {
            max = std::max(max, p->max);
            buc[p->max]++;
        }
        for (int i = 1; i <= max; i++) buc[i] += buc[i - 1];

        topo.resize(_curr - _pool);
        for (Node *p = _pool; p != _curr; p++) topo[--buc[p->max]] = p;

        return topo;
    }

    void calc() {
        toposort();

        for (int i = topo.size() - 1; i; i--) topo[i]->next->posCnt += topo[i]->posCnt;
    }
} sam;

int main() {

    return 0;
}

results matching ""

    No results matching ""