首页 > 其他 > 详细

Victor and String[Bestcoder #52 1004](回文树)

时间:2020-02-12 14:14:52      阅读:67      评论:0      收藏:0      [点我收藏+]

这是一道模板题,直接上代码。

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
const int N = 400000;
struct Plalindrome_Tree{
    int go[26], len, fail;
    ll fail_len;
}pt[N];
int pre, suf, tot;
ll ans;
int q;
int l, r;
char s[N];
void init() {
    memset(s, -1, sizeof(s));
    memset(pt, 0, sizeof(pt));
    tot = ans = 0;
    pre = suf = 0;
    l = 200000;
    r = 199999;
}
void build() {
    pt[++tot].len = -1;
    pt[0].fail = pt[1].fail = 1;
    pt[0].fail_len = 2;
    pt[1].fail_len = 1;
}
void add_back(int c) {
    int p = suf;
    while (s[r - pt[p].len - 1] != s[r]) p = pt[p].fail;
    if (!pt[p].go[c]) {
        int v = ++tot, k = pt[p].fail;
        pt[v].len = pt[p].len + 2;
        while (s[r - pt[k].len - 1] != s[r]) k = pt[k].fail;
        pt[v].fail = pt[k].go[c];
        pt[v].fail_len = pt[pt[k].go[c]].fail_len + 1;
        pt[p].go[c] = v;
    }
    suf = pt[p].go[c];
}
void add_front(int c) {
    int p = pre;
    while (s[l + pt[p].len + 1] != s[l]) p = pt[p].fail;
    if (!pt[p].go[c]) {
        int v = ++tot, k = pt[p].fail;
        pt[v].len = pt[p].len + 2;
        while (s[l + pt[k].len + 1] != s[l]) k = pt[k].fail;
        pt[v].fail = pt[k].go[c];
        pt[v].fail_len = pt[pt[k].go[c]].fail_len + 1;
        pt[p].go[c] = v;
    }
    pre = pt[p].go[c];
}
int main() {
    while (cin >> q) {
        init();
        build();
        while (q--) {
            int opt;
            char ch;
            cin >> opt;
            switch (opt) {
                case 1:
                    cin >> ch;
                    s[--l] = ch;
                    add_front(ch - a);
                    ans += pt[pre].fail_len - 2;
                    if (pt[pre].len == r - l + 1) suf = pre;
                    break;
                case 2:
                    cin >> ch;
                    s[++r] = ch;
                    add_back(ch - a);
                    ans += pt[suf].fail_len - 2;
                    if (pt[suf].len == r - l + 1) pre = suf;
                    break;
                case 3:
                    cout << tot - 1;
                    puts("");
                    break;
                case 4:
                    cout << ans;
                    puts("");
                    break;
                default:
                    puts("Wrong Input");
                    break;
            }
        }

    }
    return 0;
}

Victor and String[Bestcoder #52 1004](回文树)

原文:https://www.cnblogs.com/zcr-blog/p/12298888.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!