• BZOJ 1014: [JSOI2008]火星人prefix


    二次联通门 : BZOJ 1014: [JSOI2008]火星人prefix

    /*
        BZOJ 1014: [JSOI2008]火星人prefix
    
        Splay维护Hash值
        先建树
        重点是对于插入操作,
        找到那个位置后,像链表一样更改顺序,后将这点向上一条链更新一下hash值就好
    */
    #include <cstdio>
    #include <iostream>
    typedef long long LL;
    #include <cstring>
    #define Max 150000
    #define BASE 257
    #define rg register
    int N, M; unsigned long long mi[Max];
    inline void read (int &n)
    {
        rg char c = getchar ();
        for (n = 0; !isdigit (c); c = getchar ());
        for (; isdigit (c); n = n * 10 + c - '0', c = getchar ());
    }
    struct SD
    {
        SD *c[2], *f; unsigned long long h; int s; char r;
        inline void Up ()
        {
            s = c[0]->s + c[1]->s + 1;
            h = c[0]->h + r * mi[c[0]->s] + c[1]->h * mi[c[0]->s + 1];
        }
    } *null, *Root = NULL, poor[Max], *Ta = poor;
    char line[Max];
    class SplayType
    {
        private :
    
            void R (SD *&n)
            {
                SD *F = n->f, *G = F->f; int p = n == F->c[1];
                if ((F->c[p] = n->c[p ^ 1]) != null) F->c[p]->f = F;
                F->f = n, n->c[p ^ 1] = F;
                if ((n->f = G) != null) G->c[F == G->c[1]] = n;
                F->Up (), n->Up ();
            }
            
            void Splay (SD *&n, SD *&t)
            {
                for (SD *F; (F = n->f) != t; R (n))
                    if (F->f != t) R ((F->c[1] == n) == (F->f->c[1] == F) ? F : n);
                if (t == null) Root = n;
            }
            
        public :
            
            SD *Gkth (int k)
            {
                SD *n = Root; 
                for (; k && n != null; )
                {
                    if (n->c[0]->s >= k) n = n->c[0];
                    else if (n->c[0]->s + 1 == k) return n;
                    else k -= n->c[0]->s + 1, n = n->c[1];
                }
                return n;
            }
    
            SD *Build (int l, int r)
            {
                if (l > r) return null; int m = l + r >> 1;
                SD *n = ++ Ta; n->r = line[m];
                if ((n->c[0] = Build (l, m - 1)) != null) n->c[0]->f = n;
                if ((n->c[1] = Build (m + 1, r)) != null) n->c[1]->f = n;
                n->Up (); return n;
            }
            
            inline void I (int pos, char r)
            {
                SD *n = ++ Ta, *p = Gkth (pos); n->r = r;
                n->c[0] = null, n->c[1] = p->c[1], n->f = p;
                n->c[1]->f = n, p->c[1] = n, n->Up ();
                for (; p != null; p->Up (), p = p->f);
            }
            
            inline void C (int pos, char r)
            {
                SD *p = Gkth (pos), *n; p->r = r;
                for (n = p; n != null; n->Up (), n = n->f);
            }
            
            inline unsigned long long Q (int l, int r)
            {
                SD *L = Gkth (l - 1), *R = Gkth (r + 1);
                Splay (L, null), Splay (R, L); return R->c[0]->h;
            }
    } S;
    
    int Main ()
    {
        scanf ("%s", line + 2); N = strlen (line + 2); read (M); rg int i, j;
        null = new SD; null->c[0] = null->c[1] = null->f = null; null->s = null->h = null->r = 0;
        for (mi[0] = i = 1; i < Max; ++ i) mi[i] = mi[i - 1] * BASE; 
        line[1] = '~', line[N + 2] = '!', Root = S.Build (1, N + 2);
        Root->f = null; int x, y, s, l, r, m; 
        for (char c; M; -- M)
        {
            for (; c = getchar (), c < 'A'; );
            if (c == 'Q')
            {
                read (x), read (y), ++ x, ++ y;
                if (S.Gkth (x)->r != S.Gkth (y)->r) { puts ("0");  continue; }
                for (s = l = 1, r = N - (x < y ? y : x) + 2; l <= r; )
                {
                    m = l + r >> 1;
                    if (S.Q (x, x + m - 1) == S.Q (y, y + m - 1)) l = (s = m) + 1; 
                    else r = m - 1;
                }
                printf ("%d
    ", s);
            }
            else 
            {
                y = c == 'R', N += y ^ 1;
                read (x), ++ x; for (; c = getchar (), c < 'a'; );
                if (y) S.C (x, c); else S.I (x, c);
            }
        }
        return 0;
    }
    int ZlycerQan = Main (); int main (int argc, char *argv[]) {;}
  • 相关阅读:
    PAT甲级——A1113 Integer Set Partition
    PAT甲级——A1112 Stucked Keyboard【20】
    PAT甲级——A1111 Online Map【30】
    左神算法书籍《程序员代码面试指南》——2_12将搜索二叉树转换成双向链表【★★】
    PAT甲级——A1110 Complete Binary Tree【25】
    PAT甲级——A1109 Group Photo【25】
    PAT甲级——A1108 Finding Average【20】
    左神算法书籍《程序员代码面试指南》——2_12将搜索二叉树转换成双向链表
    PAT甲级——A1107 Social Clusters
    shiro 框架
  • 原文地址:https://www.cnblogs.com/ZlycerQan/p/7575560.html
Copyright © 2020-2023  润新知