More than 2019 cattle off summer school camp (sixth) C - Palindrome Mouse (palindrome automata)

https://ac.nowcoder.com/acm/contest/886/C

The meaning of problems: given a string of A, which is a set S A palindromic sequence string, the number string of (a, b), b is now to find a set S which

 

Analysis: palindrome string Well, the first wave of blind guess palindrome automata: We now know palindrome automatic machine schematics can be drawn, it is actually two trees with vertices 0 and 1

Suppose now that for a contribution XXXabccbaXXX now found a point, we found that it is outwardly inwardly layers -1 * number of layers, for example, now a layer 3 outwardly, inwardly 2 layer, comprising a. the answer is .... a 2 * 3-1 kinds, -1 is subtracted itself because it is impossible to choose abccba, abccba Well, it is a a (mean per se can not vote twice)

Fail to find out the number of layers is then directly up, go down next to use

#include <bits / STDC ++ H.>
 the using  namespace STD; 

const  int MAXN = 100005 ;
 const  int N = 26 is ; 
typedef Long  Long LL;
 struct Palindromic_Tree {
     int Next [MAXN] [N]; // Next pointer, next pointer, and trie Similarly, the current string pointed ends constituting the character string plus the same 
    int fail [MAXN]; // fail pointer, the node jumps to the fail mismatch pointer 
    LL CNT [MAXN]; // indicate nodes (not complete, and finally when the achievements obtained count () function after the run again is correct) essentially different from the number represented by the i strings 
    int NUM [MAXN]; // represents back to the longest represented by node i rightmost end point is the number of text strings palindromic sequence palindromic sequence ending 
    int len [MAXN];// len [i] indicates the length of a palindromic sequence represented by node i (a node represents a palindromic sequence) 
    int S [MAXN]; // store the added character 
    int Last; // formed after adding a letter to the new longest palindromic sequence represented by the node. 
    int n-; // represents the number of characters to add. 
    int P; // represents the number of nodes added. 
    Up LL [MAXN], Down [MAXN];
     BOOL VIS [MAXN];
     int newNode ( int L) { // create a new node 
        for ( int I = 0 ; I <N; I ++) Next [P] [I] = 0 ; 
        CNT [P] = 0 ; 
        NUM [P] = 0; 
        Len [P] = L;
         return P ++ ; 
    } 

    void the init () { // Initialization 
        P = 0 ; 
        newNode (   0 ); 
        newNode ( - . 1 ); 
        Last = 0 ; 
        n- = 0 ; 
        S [n-] = - . 1 ; // beginning of a character set character is not put to reduce Laid sentence 
        Fail [ 0 ] = . 1 ; 
    } 

    int get_fail ( intX) { // and as KMP, to find a longest possible mismatch after 
        the while (S [n-- len [X] - . 1 ] = S [n-]) = X! Fail [X];
         return X; 
    } 

    void the Add ( int C) { 
        C - = ' a ' ; 
        S [ ++ n-] = C;
         int CUR = get_fail (last); // by a palindromic sequence to find the matching position palindrome string 
        IF ! (Next [CUR] [C]) { // If there have been no palindromic sequence, indicate that there is a new different nature palindromic sequence 
            int now newNode = (len [CUR] + 2 ); // new node
            fail [now] Next = [get_fail (fail [CUR])] [C]; // and AC machines as automatic fail to establish a pointer, the jump to the mismatch 
            Next [CUR] [C] = now; 
            NUM [now] NUM = [Fail [now]] + . 1 ; 
        } 
        Last = Next [CUR] [C]; 
        CNT [Last] ++ ; 
    } 

    void COUNT () {
         for ( int I = P - . 1 ; I> = 0 ; - - I) CNT [Fail [I]] + = CNT [I];
         // father son accumulated cnt, because if the fail [v] = u, then u must be palindromic sequence sub v! 
    }
     Int DFS ( int  RT) {
       up [RT]=0;
       vector<int> A;
       for(int i=rt ; i>1 ; i=fail[i])
       {
           if(vis[i]!=0) break;
           vis[i]=rt;
           A.push_back(i);
           up[rt]++;///统计向外有多少
       }
       down[rt]=1;
       for(int i=0 ; i<26 ; i++)
       {
           IF(Next [RT] [I] == 0 ) Continue ; 
           Down [RT] + = DFS (Next [RT] [I]); /// statistical number downward 
       }
        for ( int I = a.size () - . 1 ; I> = 0 ; i-- ) 
        VIS [A [I]] = 0 ;
        return Down [RT]; 


    } 
    LL Solve () { 
       LL ANS = 0 ; 
       dfs ( 0 ); /// even length 
       dfs ( 1 ); /// odd length 
       for ( int I = 2; I <P; I ++ ) 
        ANS + Down = [I] * up [I]; /// current value equal to I * out how much inward 
       return ans- (p- 2 ); /// subtracts itself, the number of vertices (deduplication) 
    } 
} Tree; 

char a [MAXN];
 int main () 
{ 


    int T;
     int CT = . 1 ; 
    Scanf ( " % D " , & T);
     the while (T-- ) 
    { 
        Scanf ( " % S " , A); 
        Tree.init (); 
        int len = strlen (A);
         for(int i=0;i<len;i++)
            Tree.add(a[i]);
        printf("Case #%d: ",ct++);
        printf("%lld\n",Tree.solve());
    }
}
View Code

 

Guess you like

Origin www.cnblogs.com/shuaihui520/p/11298660.html