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;
}

 

posted @ 2018-09-08 17:26  天之道,利而不害  阅读(206)  评论(0编辑  收藏  举报