【Manacher】Colorful String
The value of a string s is equal to the number of different letters which appear in this string. Your task is to calculate the total value of all the palindrome substring. Input The input consists of a single string |s|(1≤∣s∣≤3×10^5 ). The string s only contains lowercase letters. Output Output an integer that denotes the answer. 样例输入 abac 样例输出 6 样例解释 abac has palindrome substrings a,b,a,c,abaa,b,a,c,aba,ans the total value is equal to 1+1+1+1+2=6。
【题解】
Manacher,先预处理一波,然后找出每一个位置的26个字母下一个位置,存在一个vector里面,然后最后找的时候就是差值 × 对应的个数。
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int N=3e5+100; 5 char S[N],T[N<<1]; 6 int Len[N*2]; 7 int nxt[N][27]; 8 vector<int>V[N]; 9 void Manacher(char *s){ 10 int L=strlen(s); 11 int po = 0 , mx=0 ; 12 13 for(int i=1;i<=L*2;i++){ 14 T[i] = i&1? '#' : s[i/2-1] ; 15 } 16 17 T[0] = '@'; 18 T[2*L+1] = '#'; 19 T[2*L+2] = '\0'; 20 21 ll tmp = 0 ; 22 for(int i=1;i<=2*L;i++){ 23 if( i<mx ){ 24 Len[i]=min( mx-i , Len[2*po-i] ); 25 }else{ 26 Len[i] = 1 ; 27 } 28 29 while( T[i+Len[i]]==T[i-Len[i]] ){ 30 Len[i]++; 31 } 32 if( i + Len[i] > mx ){ 33 po = i; 34 mx = i + Len[i]; 35 } 36 } 37 } 38 int main() 39 { 40 scanf("%s",S); 41 Manacher(S); 42 int len1 = strlen( S ) ; 43 int len2 = strlen( T ) ; 44 45 for( int j = 0 ; j < 26 ; j++ ){ 46 int pos = INT_MAX ; 47 for( int i = len1 - 1 ; i >= 0 ; i-- ){ 48 if( S[i] == j + 'a' ) pos = i ; 49 nxt[i][j] = pos ; 50 } 51 } 52 53 54 for( int i = 0 ; i < len1 ; i++ ){ 55 for( int j = 0 ; j < 26 ; j++ ){ 56 V[i].push_back( nxt[i][j] ) ; 57 } 58 sort( V[i].begin() , V[i].end() ); 59 } 60 /* 61 for( int i = 1 ; i < len2 ; i++ ){ 62 printf("%d : %c , Len %d \n",i , T[i] , Len[i] ); 63 } 64 */ 65 ll ans = 0 ; 66 for( int i = 2 ; i < len2 ; i++ ){ 67 int L = Len[i] / 2 ; 68 if( L == 0 ) continue ; 69 70 int Id = i / 2 - 1 ; 71 if( i & 1 ) Id ++ ; 72 73 int RR = Id + L - 1 ; 74 int Last = V[Id][0] ; 75 int cnt = 0 ; 76 for( auto x : V[Id] ){ 77 if( x > RR ) break ; 78 int r = x - 1 ; 79 ans = ans + (ll)( cnt ++ ) * (ll) ( r - Last + 1 ); 80 Last = x ; 81 } 82 if( RR >= Last ){ 83 ans = ans + (ll) cnt * (ll) ( RR - Last + 1 ); 84 } 85 } 86 printf("%lld\n",ans); 87 return 0; 88 } 89 90 //jswbutgecnmqnuagqnvxfljfffzvudcfvygpro