• 板子们~


    要省选啦!码码板子…… 

    const int N = 200010;
    char st[N];
    int rk[N], sa[N], nr[N], ns[N], tab[N], hi[N];
    void calc(int n)
    {
        for (int i = 0; i <= 26; ++ i) tab[i] = 0;
        for (int i = 1; i <= n; ++ i) tab[st[i] - 'a' + 1] = 1;
        for (int i = 1; i <= 26; ++ i) tab[i] += tab[i - 1];
        for (int i = 1; i <= n; ++ i) rk[i] = tab[st[i] - 'a' + 1];
        for (int p = 2; (p >> 1) <= n; p <<= 1)
        {
            for (int i = 0; i <= n; ++ i) tab[i] = 0;
            for (int i = 1; i <= n; ++ i) tab[rk[i + (p >> 1)]] ++;
            for (int i = 1; i <= n; ++ i) tab[i] += tab[i - 1];
            for (int i = n; i >= 1; -- i) ns[tab[rk[i + (p >> 1)]] --] = i;
            for (int i = 0; i <= n; ++ i) tab[i] = 0;
            for (int i = 1; i <= n; ++ i) tab[rk[i]] ++;
            for (int i = 1; i <= n; ++ i) tab[i] += tab[i - 1];
            for (int i = n; i >= 1; -- i) sa[tab[rk[ns[i]]] --] = ns[i];
            nr[sa[1]] = 1;
            for (int i = 2; i <= n; ++ i)
                if (rk[sa[i]] == rk[sa[i - 1]] && rk[sa[i] + (p >> 1)] == rk[sa[i - 1] + (p >> 1)])
                    nr[sa[i]] = nr[sa[i - 1]];
                else
                    nr[sa[i]] = nr[sa[i - 1]] + 1;
            for (int i = 1; i <= n; ++ i)
                rk[i] = nr[i];
            if (rk[sa[n]] == n) break;
        }
        for (int i = 1; i <= n; ++ i)
            if (rk[i] != 1)
            {
                hi[rk[i]] = max(hi[rk[i - 1]] - 1, 0);
                while (st[i + hi[rk[i]]] == st[sa[rk[i] - 1] + hi[rk[i]]])
                    hi[rk[i]] ++;
            }
    }
    SA

    这个SA奇满无比…… 但至少能用?

    const int N = 200000;
    int nxt[N][30], par[N], len[N], tot;
    int append(int p, int c)
    {
        if (nxt[p][c] && len[nxt[p][c]] == len[p] + 1) return nxt[p][c];
        int np = ++ tot, f = nxt[p][c]; len[np] = len[p] + 1;
        while (p && !nxt[p][c]) nxt[p][c] = np, p = par[p];
        if (!p) par[np] = 1;
        else
        {
            int q = nxt[p][c];
            if (len[q] == len[p] + 1) par[np] = q;
            else
            {
                int nq = f ? np : ++ tot;
                len[nq] = len[p] + 1;
                memcpy(nxt[nq], nxt[q], sizeof(nxt[q]));
                par[nq] = par[q]; par[q] = nq; if (!f) par[np] = nq;
                while (p && nxt[p][c] == q) nxt[p][c] = nq, p = par[p];
            }
        }
        return np;
    }
    SAM

    这个SAM应该是真的SAM!建在trie树上不会有无用节点~

    const int N = 200000;
    char st[N]; int n, len[N];
    void manacher(int n)
    {
        int md = 0, mx = 0;
        for (int i = 1; i <= n; ++ i)
        {
            if (mx >= i) len[i] = min(mx - i, len[md * 2 - i]);
            while (st[i + len[i]] == st[i - len[i]]) len[i] ++;
            if (i + len[i] > mx) mx = i + len[i], md = i;
        }
    }
    manacher

    马拉车~

    const int N = 200000;
    char st[N];
    int nxt[N][30], par[N], len[N], n, tot, p;
    int append(int p, int c, int i)
    {
        while (st[i] != st[i - len[p] - 1]) p = par[p];
        if (!nxt[p][c])
        {
            int np = nxt[p][c] = ++ tot;
            len[np] = len[p] + 2;
            int q = par[p];
            while (q && !nxt[q][c]) q = par[q];
            if (!q) par[np] = 2;
            else par[np] = nxt[q][c];
        }
        return nxt[p][c];
    }
    eertree

    PAM好像非常短的样子呢

    const int N = 200000;
    char st[N]; int n;
    int calc(int n)
    {
        int i = 1, j = 2, k = 0;
        for (; i <= n && j <= n && k < n; )
        {
            int si = st[i + k > n ? i + k - n : i + k],
                sj = st[j + k > n ? j + k - n : j + k];
            if (si == sj) k ++;
            else
            {
                if (si < sj) j += k + 1;
                else i += k + 1;
                k = 0;
                if (i == j) j ++;
            }
        }
        return min(i, j);
    }
    minRepr

    以前从来没有写过最小表示法QAQ

    好像都是字符串算法,补一些其他的东西吧

    struct treap
    {
        treap *left, *right;
        int siz, val;
    
    treap ()
    {
        left = right = NULL; siz = val = 0;
    }
    
    treap *update()
    {
        this->siz = 1;
        if (this->left != NULL) this->siz += this->left->siz;
        if (this->right != NULL) this->siz += this->right->siz;
        return this;
    }
    
    treap *push_down()
    {
        return this;
    }
    
    treap *append(treap *p)
    {
        this->siz += p->siz;
        return this;
    }
    
    };
    
    treap *join(treap *t1, treap *t2)
    {
        if (t1 == NULL) return t2;
        if (t2 == NULL) return t1;
        if (rand() % (t1->siz + t2->siz) < t1->siz)
        {
            t1->push_down();
            t1->right = join(t1->right, t2);
            return t1->update();
        }
        else
        {
            t2->push_down();
            t2->left = join(t1, t2->left);
            return t2->update();
        }
    }
    
    auto split(treap *t, treap *p)
    {
        if (t == NULL)
            return make_pair((treap*)NULL, (treap*)NULL);
        t->push_down();
        if (p->val < t->val)
        {
            auto f = split(t->left, p);
            t->left = f.second;
            return make_pair(f.first, t->update());
        }
        else
        {
            auto f = split(t->right, p);
            t->right = f.first;
            return make_pair(t->update(), f.second);
        }
    }
    
    treap *insert(treap *t, treap *p)
    {
        if (t == NULL || rand() % (t->siz + 1) == 0)
        {
            auto f = split(t, p);
            p->left = f.first; p->right = f.second;
            return p->update();
        }
        else
        {
            t->push_down();
            if (p->val < t->val)
                t->left = insert(t->left, p);
            else
                t->right = insert(t->right, p);
            return t->append(p);
        }
    }
    
    treap *erase(treap *t, treap *p)
    {
        if (t == NULL) return NULL;
        t->push_down();
        if (t->val == p->val)
            return join(t->left, t->right);
        else if (p->val < t->val)
            t->left = erase(t->left, p);
        else
            t->right = erase(t->right, p);
        return t->update();
    }
    
    treap *merge(treap *t1, treap *t2)
    {
        if (t1 == NULL) return t2;
        if (t2 == NULL) return t1;
        if (rand() % (t1->siz + t2->siz) < t2->siz)
            swap(t1, t2);
        auto f = split(t2, t1);
        t1->push_down();
        t1->left = merge(t1->left, f.first);
        t1->right = merge(t1->right, f.second);
        return t1->update();
    }
    treap

    一棵非常优秀的二叉排序树,可以在上面套其他数据结构!(不过二叉排序树上怎么套东西?

  • 相关阅读:
    Win32基础知识2 Win32汇编语言003
    Win32基础知识4 Win32汇编语言005
    Win32基础知识4 Win32汇编语言005
    第一个程序 零基础入门学习Delphi01
    Mysql四种通信协议(linux下本地连接的都是socket 其他都是tcp)
    Rhino
    Common Gateway Interface Python CGI编程
    inaccessible
    mysqli_report
    算法功底网站性能瓶颈
  • 原文地址:https://www.cnblogs.com/AwD-/p/8583848.html
Copyright © 2020-2023  润新知