【HDU】5421 Victor and String【回文树扩展——可左右添加字符的回文树】

来源:互联网 发布:网络课程app 编辑:程序博客网 时间:2024/06/08 10:59

传送门:【HDU】5421 Victor and String

能维护左右最长回文的前提是要知道除了上一个节点表示的最长回文串能更新出新的本质不同的回文串外,其他节点都做不到(比赛的时候就是这个性质没想清楚,然后想了个O(N2)的做法……),这个可以YY一下,想清楚了就简单了,分别维护左右last指针,然后用一棵回文树实现这个过程,具体过程我就不多说了。

my  code:

#include <stdio.h>#include <string.h>#include <algorithm>using namespace std ;typedef long long LL ;#define clr( a , x ) memset ( a , x , sizeof a )const int MAXN = 200005 ;struct Palindromic_Tree {    int nxt[MAXN][26] ;    int fail[MAXN] ;    int len[MAXN] ;    int S[MAXN] , L , R ;    int num[MAXN] ;    int last[2] ;    int p ;    LL tot ;    int newnode ( int l ) {        for ( int i = 0 ; i < 26 ; ++ i ) nxt[p][i] = 0 ;        num[p] = 0 ;        len[p] = l ;        return p ++ ;    }    void init ( int n ) {        p = 0 ;        newnode ( 0 ) ;        newnode ( -1 ) ;        clr ( S , -1 ) ;        L = n ;        R = n - 1 ;        last[0] = last[1] = 1 ;        fail[0] = 1 ;        tot = 0 ;    }    int get_fail ( int v , bool d ) {        if ( d ) while ( S[R - len[v] - 1] != S[R] ) v = fail[v] ;        else while ( S[L + len[v] + 1] != S[L] ) v = fail[v] ;        return v ;    }    void add ( int c , bool d ) {        if ( d ) S[++ R] = c ;        else S[-- L] = c ;        int cur = get_fail ( last[d] , d ) ;        if ( !nxt[cur][c] ) {            int now = newnode ( len[cur] + 2 ) ;            fail[now] = nxt[get_fail ( 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]] ;    }} ;Palindromic_Tree T ;int n ;void solve () {    int op ;    char c ;    T.init ( n ) ;    for ( int i = 0 ; i < n ; ++ i ) {        scanf ( "%d" , &op ) ;        if ( op <= 2 ) {            scanf ( " %c" , &c ) ;            T.add ( c - 'a' , op - 1 ) ;        }        if ( op == 3 ) printf ( "%d\n" , T.p - 2 ) ;        if ( op == 4 ) printf ( "%I64d\n" , T.tot ) ;    }}int main () {    while ( ~scanf ( "%d" , &n ) ) solve () ;    return 0 ;}
0 0
原创粉丝点击