【回文自动机】 HDU 5421 Victor and String

通道

题意:首尾加字符,询问多少个本质不同的回文串和多少个不同回文串

思路:标记即可,分别维护左右last指针

代码:

#include <cstdio>
#include <cstring>
typedef long long ll;
template <class T>
inline bool rd(T &ret) {
    char c; int sgn;
    if(c = getchar() , c == EOF) return false;
    while(c != '-' && (c < '0' || c > '9')) c = getchar();
    sgn = (c == '-') ? -1 : 1;
    ret = (c == '-') ? 0 : (c - '0');
    while(c = getchar(), c >= '0' && c <= '9') ret = ret * 10 + (c - '0');
    ret *= sgn;
    return true;
}
const int MAX_N = 600005;
const int SIG = 26;
int n;
struct PTree {
    int nxt[MAX_N][SIG], fail[MAX_N], cnt[MAX_N], num[MAX_N], len[MAX_N], S[MAX_N];
    int last[2], L, R, p;
    ll tot;
    int newNode (int l) {
        memset(nxt[p], 0, sizeof nxt[p]);
        cnt[p] = num[p] = 0;
        len[p] = l;
        return p++;
    }
    void init() {
        p = tot = 0;
        newNode(0), newNode(-1);
        L = n, R = n - 1;
        for (int i = 0; i < 2 * n; ++i) S[i] = -1;
        last[0] = last[1] = 1;
        fail[0] = 1;
    }
    int getFail(int x, bool d) {
        if (d) while (S[R - len[x] - 1] != S[R]) x = fail[x];
        else while (S[L + len[x] + 1] != S[L]) x = fail[x];
        return x;
    }
    void add(int c, bool d) {
        c = c - 'a';
        if (d) S[++R] = c;
        else S[--L] = c;
        int cur = getFail(last[d], d);
        if (!nxt[cur][c]) {
            int now = newNode(len[cur] + 2);
            fail[now] = nxt[getFail(fail[cur], d)][c];
            nxt[cur][c] = now;
            num[now] = num[fail[now]] + 1;
        }
        last[d] = nxt[cur][c];
        if (len[last[d]] == R - L + 1) last[d ^ 1] = last[d];
        tot += num[last[d]];
    }    
};

PTree T;
char str[2];
int main() {
    while (1 == scanf("%d", &n)) {
        T.init();
        while (n-- > 0) {
            int opt;rd(opt);
            if (opt < 3) scanf("%s", str), T.add(str[0], opt - 1);
            else if (opt == 3) printf("%d\n", T.p - 2);
            else printf("%I64d\n", T.tot);
        }
    }
    return 0;
}
View Code

 

posted @ 2015-09-01 14:19  mithrilhan  阅读(115)  评论(0编辑  收藏  举报