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