Topic links
Test Instructions: give you a string, want you to divide it into two strings, so that the essence of the left side of the string of the number of palindrome string is twice times the right string, for each such sub-division, its contribution to the answer is the length of the left string, now you find all such division, and will contribute to the answer MoD 1e9+7
Analysis:
Run from left to right side palindrome automata, for each prefix
Can tell how many of these palindrome strings are essentially different.
The number of palindrome strings that are essentially different is actually the number of automata nodes-2
Well, after the prefix, we can get all the characters that can be used as the left part string. Number of palindrome strings
Because it is a palindrome string, so we run backwards, we can also get to the right part of the string of the essence of different palindrome string number
Final violence check once for each position whether there is a reasonable division of test instructions, if there is the left part of the length of the tired ride up
#include <bits/stdc++.h>#defineLL Long Long#defineULL unsigned long Long#defineSCL (i) scanf ("%lld", &i)#defineSCLL (i, J) scanf ("%lld%lld", &i, &j)#defineSclll (I, J, K) scanf ("%lld%lld%lld", &i, &j, &k)#defineScllll (I, J, K, L) scanf ("%lld%lld%lld%lld", &i, &j, &k, &l)#defineSCS (i) scanf ("%s", I)#defineSCI (i) scanf ("%d", &i)#defineSCD (i) scanf ("%lf", &i)#defineScIl (i) scanf ("%i64d", &i)#defineScii (i, J) scanf ("%d%d", &i, &j)#defineSCDD (i, J) scanf ("%lf%lf", &i, &j)#defineScill (i, J) scanf ("%i64d%i64d", &i, &j)#defineSCIII (I, J, K) scanf ("%d%d%d", &i, &j, &k)#defineSCDDD (I, J, K) scanf ("%lf%lf%lf", &i, &j, &k)#defineScilll (I, J, K) scanf ("%i64d%i64d%i64d", &i, &j, &k)#defineSCIIII (I, J, K, L) scanf ("%d%d%d", &i, &j, &k, &l)#defineSCDDDD (I, J, K, L) scanf ("%lf%lf%lf%lf", &i, &j, &k, &l)#defineScillll (I, J, K, L) scanf ("%i64d%i64d%i64d%i64d", &i, &j, &k, &l)#defineLson L, M, rt<<1#defineRson m+1, R, rt<<1|1#defineLowbit (i) (I & (i))#defineMem (i, J) memset (i, J, sizeof (i))#defineFIR First#defineSEC Second#defineVI vector<int>#defineINS (i) Insert (i)#definePB (i) push_back (i)#definePII Pair<int, int>#defineVL Vector<long long>#defineMK (i, J) Make_pair (I, J)#defineAll (i) I.begin (), I.end ()#definePLL Pair<long Long, long long>#define_time 0#define_input 0#define_output 0clock_t START, END;void__sttime ();void__entime ();void__ioput ();using namespacestd;Const intMAXN =400000;Const intN = - ;structPalindromic_tree {intNext[maxn][n];//next pointer, the next pointer is similar to the dictionary tree, and the string pointing to the current string consists of the same character . intFAIL[MAXN];//fail pointer, which jumps to the node pointed to by the fail pointer after mismatch intCNT[MAXN];//Number of occurrences of palindrome represented by node I, note the last call to the Count function to complete the calculation intNUM[MAXN];//The most right end of the longest palindrome string in node I is the number of palindrome ends of palindrome string (unverified) intLEN[MAXN];//Len[i] Indicates the length of the palindrome string represented by node I intS[MAXN];//storing the added characters intLast;//point to the node where the previous character is located, to facilitate the next add intn;//character array Pointer inttot;//Node Pointers intNewNode (intL) {//new Node for(inti =0; i < N; + + i) next[tot][i] =0 ; Cnt[tot]=0 ; Num[tot]=0 ; Len[tot]=l; returnTot + + ; } voidInit () {//Initializetot =0 ; NewNode (0 ) ; NewNode (-1 ) ; Last=0 ; N=0 ; S[n]= -1;//start with a character that is not in a character set, reducing the special sentencefail[0] =1 ; } intGet_fail (intx) {//As with KMP, find the one that is as long as possible after mismatch. while(S[n-len[x]-1] = S[n]) x =Fail[x]; returnx; } voidAdd (intc) {c-='a' ; s[+ + N] =C; intCur = get_fail (last);//find the matching position of this palindrome by the last palindrome string. if(!next[cur][c]) {//If this palindrome does not appear, there is a new and different nature of the palindrome string intnow = NewNode (Len[cur] +2) ;//new NodeFail[now] = Next[get_fail (Fail[cur])][c];//Create a fail pointer like an AC automaton to jump after mismatchNEXT[CUR][C] =Now ; Num[now]= Num[fail[now]] +1 ; } Last=Next[cur][c]; Cnt[last]++ ; } voidcount () { for(inti = tot-1; I >=0; --i) cnt[fail[i] + =Cnt[i]; //The father accumulates the CNT of the son, because if fail[v]=u, then u must be a sub-palindrome of V! }}pam1, PAM2;ConstLL mod = 1e9 +7;CharSTR[MAXN]; LL L[MAXN], R[MAXN];intMainvoid) {__sttime (); __ioput (); intT; SCI (T); while(t--) {mem (L,0); Mem (R,0); Pam1.init (); Pam2.init (); SCS (str); intLen =strlen (str); for(intI=0; i<len; i++) {Pam1.add (str[i]); L[i]= Pam1.tot-2; } for(inti=len-1; i>=0; i--) {Pam2.add (str[i]); R[i]= Pam2.tot-2; } LL ans=0; for(intI=0; i<len; i++){ if(L[i] = =2* r[i+1]){ if(ans = =0) ans =1LL; Ans= (1LL * (i+1) * ans)%MoD; }} printf ("%lld\n", ans); }__entime ();return 0;}void__sttime () {#if_timeSTART=clock (); #endif}void__entime () {#if_timeEND=clock (); Cerr<<"Execute time ="<< (Double) (End-start)/clocks_per_sec<<Endl; #endif}void__ioput () {#if_inputFreopen ("In.txt","R", stdin); #endif #if_outputFreopen ("OUT.txt","W", stdout); #endif}
View Code
WHU 583 palindrome (palindrome automaton && the number of different palindrome strings in nature)