• Skr


    ps:听说是回文树的模板题,就马上学了一波。理解了fail指针就行了。

    建议看WWT的论文;

    这两行代码坑我好久:(红色那句一定要放在最后)因为 tp == last 的时候,当前节点的fail指针可能指向自己。

    node[tot].fail = node[tp].ch[s[i] - '0'];
    node[last].ch[s[i] - '0'] = tot;
    const int N = 2000006;
    const int mod = 1000000007;
    LL qpow(LL a, LL b) {
        if (!b) return 0;
        LL c = 1;
        for (; b; a = a * a % mod, b >>= 1) if (b & 1) c = c * a % mod;
        return c;
    }
    struct data {
        int len, fail;
        int ch[10];
    };
    struct PldTree {
        LL ans;
        LL num[N];
        int tot, last;
        char s[N];
        data node[N];
        void Inite() {
            tot = last = 1;
            node[0].fail = 1;
            node[1].len = -1;
            num[1] = num[0] = 0;
        }
        void Insert(int i) {
            while(s[i] != s[i - node[last].len - 1]) last = node[last].fail;
            if (!node[last].ch[s[i] - '0']) {
                node[++tot].len = node[last].len + 2;
                num[tot] = ((s[i] - '0') * qpow(10, node[last].len + 1) % mod + 10 * num[last] % mod + (s[i] - '0')) % mod;
                int tp = node[last].fail;
                while(s[i] != s[i - node[tp].len - 1]) tp = node[tp].fail;
                node[tot].fail = node[tp].ch[s[i] - '0'];
                node[last].ch[s[i] - '0'] = tot;
                last = tot;
            }
            else last = node[last].ch[s[i] - '0'];
        }
        LL sum() {
            ans = 0;
            Rep(i, 2, tot) ans = (ans + num[i]) % mod;
            return ans;
        }
        /*
        void DFS(int u, LL tp) {
            Rep(i, 1, 9) if (node[u].ch[i]) {
                LL res = (i * qpow(10, node[u].len + 1) % mod + 10ll * tp % mod + i) % mod;
                ans = (ans + res) % mod;
                DFS(node[u].ch[i], res);
            }
        }
        */
    };
    PldTree T;
    int main()
    {
        T.Inite();
        scanf("%s", T.s + 1);
        int n = strlen(T.s + 1);
        Rep(i, 1, n) T.Insert(i);
        pr(T.sum());
        /*
        T.ans = 0;
        T.DFS(0, 0);
        T.DFS(1, 0);
        pr(T.ans);
        */
        return 0;
    }
  • 相关阅读:
    .NET深入解析LINQ框架(四:IQueryable、IQueryProvider接口详解)
    .NET简谈组件程序设计之(初识NetRemoting)
    .NET简谈组件程序设计之(delegate与event关系)
    .NET简谈组件程序设计之(上下文与同步域)
    .NET简谈特性(代码属性)
    .NET可逆框架设计
    使用KTM(内核事务管理器)进行文件事务处理
    .NET面向上下文、AOP架构模式(实现)
    .NET简谈设计模式之(装饰者模式)
    .NET对存储过程的调用抽象封装
  • 原文地址:https://www.cnblogs.com/zgglj-com/p/9609789.html
Copyright © 2020-2023  润新知