【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
View Code

猜你喜欢

转载自www.cnblogs.com/Osea/p/11483538.html